work with std::range::subrange
hmoffatt opened this issue · 5 comments
Possibly related to #4 is it possible to make the algorithms work with subranges?
Occasionally I need to use an algorithm on a subset of a container. I like using kdalgorithms rather than STL because kdalgorithms::transformed for example returns the new container rather than requiring it to be declared in advance.
I tried this; all_of compiles, but transformed does not, complaining about missing value_type in the subrange (in MSVC 2022):
std::vector<int> test;
auto x = kdalgorithms::all_of(std::ranges::subrange(test.cbegin(), test.cend()),
[](const int i) -> bool { return i == 0; });
auto y = kdalgorithms::transformed<std::vector<int>>(std::ranges::subrange(test.cbegin(), test.cend()),
[](const int i) -> int { return i + 1; });
Thanks for the feedback. I looked shortly at subrange, and indeed I see no value_type in there, which is all over the place for kdalgorithms. I've very little insight into how std::ranges works, so I'm afraid I realistically wouldn't get to fix this.
I'll leave it open in case someone else knows of a way around this (without a huge rewrite to KDAlgorithms)
Cheers
Jesper.
It looks like there is std::ranges::range_value_t<> for this.. I don't know if this fits in with your ValueTypeHelper though.
https://stackoverflow.com/questions/74496713/how-to-get-the-type-of-the-values-in-a-c20-stdranges-range
Please try #70 which at least works with your example now.
Looks good! I tried a few things with QVector and std::vector and it worked as expected, on g++/clang++/MSVC.
I tried working on a subrange of std::map and didn't have much luck:
std::map<int, QString> test;
test[0] = "hi";
test[1] = "there";
for (auto it = test.begin(); it != test.end(); it++)
qDebug() << *it; // ok
auto sub = std::ranges::subrange(test.cbegin(), test.cend());
for (auto [k, v] : sub) // doesn't compile with clang++ 14
qDebug() << k << v;
qDebug() << kdalgorithms::transformed<std::vector<QString>>(sub,
[](const auto& v) -> QString { return v.second; });
clang++-16 returns
In file included from ./kdalgorithms.h:25:
./kdalgorithms_bits/transform.h:45:39: error: invalid reference to function 'size': constraints not satisfied
detail::reserve(result, input.size());
^
./kdalgorithms_bits/transform.h:73:16: note: in instantiation of function template specialization 'kdalgorithms::detail::transformed<std::vector<QString>, std::ranges::subrange<std::_Rb_tree_const_iterator<std::pair<const int, QString>>, std::_Rb_tree_const_iterator<std::pair<const int, QString>>, std::ranges::subrange_kind::unsized> &, (lambda at test.cpp:50:13)>' requested here
return transformed<ResultContainer>(std::forward<InputContainer>(input),
^
./kdalgorithms_bits/transform.h:108:20: note: in instantiation of function template specialization 'kdalgorithms::detail::transformed<std::vector<QString>, std::ranges::subrange<std::_Rb_tree_const_iterator<std::pair<const int, QString>>, std::_Rb_tree_const_iterator<std::pair<const int, QString>>, std::ranges::subrange_kind::unsized> &, (lambda at test.cpp:50:13)>' requested here
return detail::transformed<ResultContainer>(
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/ranges_util.h:327:30: note: because '(std::ranges::subrange_kind)false == subrange_kind::sized' evaluated to false
size() const requires (_Kind == subrange_kind::sized)
^
Similar with g++ 12 and VS 2022.
My only interest is in a subrange of a vector currently anyway. Thanks for working on this.
Implemented.