Use std::views::all or std::views::reverse conditionally at runtime

Viewed 55

I am trying to use conditionally one or other type of view based on boolean only known at runtime.

Issue here is that std::views::reverse result type is different from the result of std::views::all, so ternary operator can not work. I have also tried std::reverse of std::reverse hoping that and std::views::all will be compatible, but it also does not work.

#include <algorithm>
#include <ranges>
#include <cassert>
#include <vector>
#include <fmt/format.h>
#include <fmt/ranges.h>


void print_ascending(const std::vector<int>& sorted_data, const bool data_descending) { 
    // does not work
    //auto sorted_asc = data_descending ? std::views::reverse(sorted_data) : std::views::all(sorted_data);
    auto sorted_asc = sorted_data;
    if (data_descending) {
        std::ranges::reverse(sorted_asc);
    }
    fmt::print("{}\n", sorted_asc);
}

int main() {
    print_ascending({1,2,4}, false);
    print_ascending({8,7,4,2}, true);
}

notes:

  • boolean is only known at runtime so I can not make it compile time argument
  • I know I could probably do this with indexes or with if else (and then use .begin() and .end() or .rbegin() and .rend()), but I am looking for elegant ranges solution
  • I know many views inherit from common base type, but that type is CRTP base class, so I guess I can not use that base class pointer as you would do normally with 2 classes that derive from same base
0 Answers
Related