1

I would like to apply a projection prior to piping a range into an action or view. Consider the following example:

#include <iostream>
#include <range/v3/view/map.hpp>
#include <range/v3/action/sort.hpp>
#include <range/v3/algorithm/for_each.hpp>

int main()
{
    std::vector<std::string> strings{"1.2","100.2","11.2","0.2","2.2"};
    ranges::for_each(strings, [](const auto& str) { std::cout << str << std::endl; });
    
    strings | ranges::views::all | ranges::actions::sort;
    
    std::cout << std::endl;
    ranges::for_each(strings, [](const auto& str) { std::cout << str << std::endl; });

    return 0;
}

Say that I wish to convert the string to a double prior to sorting. Using the functional approach, this is possible:

strings |= ranges::actions::sort(std::less{}, [](const auto& str) { return std::stod(str); });

However I'm wondering if there is a pipeline format which allows this instead, which applies this projection for all following operations, for example:

strings | ranges::views::projection([](const auto&str ) { return std::stod(str); }) | ranges::actions::sort;

Note that using ranges::views::transform doesn't work as it creates a new range instead of a projection.

I'm also not sure if there's a caveat for using strings | ranges::views::all | ranges::actions::sort instead of strings |= ranges::actions::sort which is recommended in the range-v3 documentation.

singhh23
  • 97
  • 7
  • Does this answer your question? [Why can't a range be sorted in range-v3?](https://stackoverflow.com/questions/60338142/why-cant-a-range-be-sorted-in-range-v3) – jhcarl0814 Jan 15 '21 at 03:22

1 Answers1

1

Update(2021.01.26):

Doing actions on projected views might cause confusion. E.g. imagine a projection function with signature int&(std::pair<int, int>&) / int&&(std::pair<int, int>&&) that return the first component of a pair, apply that projection on a range of std::pair<int, int>. What should happen if we filter?

  • It should return a range of int because we passed it a range of int.
  • It should also return a range of std::pair<int, int> because we really want to filter the underlying range of std::pair<int, int>.

But it does not know we want which.

So it seems that it is not appropriate to treat projection as a standalone operation on range this time, instead it is more clear if the projection operation is an optional parameter of filter or sort.


Old answer(2021.01.15):

It is inefficient to implement sorting with projection and perhaps that's why it's not provided. You have to store the result of projection explicitly:
c++ - Why can't a range be sorted in range-v3? - Stack Overflow
Why can't a range be sorted in range-v3?

The standard version says the complexity of projection is (N·log(N)) (so it may be faster to project the elements and store them before sorting):
std::ranges::sort - cppreference.com
https://en.cppreference.com/w/cpp/algorithm/ranges/sort

jhcarl0814
  • 108
  • 2
  • 8
  • I guess I'm not concerned about the sort operation in particular so maybe it's a poor example. It could instead be a views::filter or other operations - the point is that I would like all following operations to consider a projection instead of having to provide the same projection to every following operation. – singhh23 Jan 15 '21 at 17:02
  • 1
    @singhh23 Doing actions on projected views might cause confusion. E.g. imagine a projection function with signature `int&(std::pair&) / int&&(std::pair&&)` that return the first component of a pair, apply that projection on a range of `std::pair`. What should happen if we `filter`? It should return a range of `int` because we passed it a range of `int`, it should also return a range of `std::pair` because we really want to filter the underlying range of `std::pair`, but it does not know we want which. – jhcarl0814 Jan 16 '21 at 23:59
  • 1
    @singhh23 So it seems that it is not appropriate to treat projection as a standalone operation on range this time, instead it is more **clear** if the projection operation is an optional parameter of `filter` or `sort`. – jhcarl0814 Jan 17 '21 at 00:00
  • a similar one: https://stackoverflow.com/questions/42727801/how-do-i-boostrangesort-a-boosttransformed-range – jhcarl0814 Jan 19 '21 at 12:49
  • Yea, your comment on return type makes sense to me - could you update your answer with it and I'll accept? – singhh23 Jan 25 '21 at 21:16
  • @singhh23 Okay, the comments are added to the answer. – jhcarl0814 Jan 26 '21 at 02:55