4

How do I join two views using std::ranges?
In ranges-v3 the views are joined with views::concat(), and I cannot figure out how to do that with std::ranges.

#include <string>
#include <iostream>
#include <vector>
#include <ranges>
using namespace std;
using namespace views;

void snake_to_camel() {   
    auto transform = views::transform;
    auto const s = string{"feel_the_force"};
    auto words = s | split('_');                        // [[f,e,e,l],[t,h,e],[f,o,r,c,e]]
    auto words_cap = words | transform([](auto word){
        auto transform = views::transform;
        auto head = word | take(1) 
                         | transform([](unsigned char c){return toupper(c);}); // e.g. [F]
        auto tail = word | drop(1);                     // e.g. [e.e.l]
        return tail;
        //return concat( head, tail );                  // e.g. [F,e,e,l] // join( head, tail ) will not work here.
    });                                                 // [[F,e,e,l],[T,h,e],[F,o,r,c,e]]
    auto s_camelcase = words_cap | join;                // [F.e.e.l.T.h.e.F.o.r.c.e]
    string res;
    for(auto c : s_camelcase)
        res.push_back(c);
    cout << res;
}

int main() {
    snake_to_camel();
    cout << endl;
}
Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
Generic Name
  • 1,083
  • 1
  • 12
  • 19
  • 1
    Tricky. Unfortunately, something like `std::array parts{head, tail}; return join(parts);` doesn't work. I'm afraid you'd have to reimplement ranges-v3's `views::concat()` yourself, or of course just use ranges-v3. – G. Sliepen Oct 15 '21 at 14:53

1 Answers1

3

C++20 cannot do this.

But benefiting from P2328 and P2210, in C++23, we can do this in another way, that is, transform the split subrange into a string, modify and return it, and finally join:

void snake_to_camel() {   
    auto transform = views::transform;
    auto const s = string{"feel_the_force"};
    auto words = s | split('_');                        // [[f,e,e,l],[t,h,e],[f,o,r,c,e]]
    auto words_cap = words | transform([](auto r) { 
                               std::string word(r);
                               word.front() = toupper(word.front());
                               return word;
                             });                        // [[F,e,e,l],[T,h,e],[F,o,r,c,e]]
    auto s_camelcase = words_cap | join;                // [F.e.e.l.T.h.e.F.o.r.c.e]
    string res;
    for(auto c : s_camelcase)
        res.push_back(c);
    cout << res;
}

Demo.

康桓瑋
  • 33,481
  • 5
  • 40
  • 90
  • Both of those are defects against C++20, so what you wrote here should be valid C++20. – Barry Oct 15 '21 at 17:04
  • Thank you for pointing it out. But how should I describe it properly? "Since C++20", "the anaphase of C++20"... – 康桓瑋 Oct 15 '21 at 17:22
  • That's a good question... since C++21? :-) Don't actually know. – Barry Oct 15 '21 at 19:27
  • Interesting, but the "snake_to_camel" is only illustration. I was hoping for as "concat" that allows me to concatenate two different views. – Generic Name Oct 16 '21 at 09:16
  • Just use range-v3, C++20 has no such thing. – 康桓瑋 Oct 16 '21 at 09:21
  • @Generic If you want to ask a question about concatenation different views, I suggest you ask _that_ question (it is not clear to me from your question that this is what you wanted). – Barry Oct 16 '21 at 20:41