https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108487
--- Comment #8 from Mark Bourgeault <Mark_B53 at yahoo dot com> ---
What about something like this?
#if __cplusplus >= 201709L
template<typename _InputIterator,
typename = std::_RequireInputIter<_InputIterator>>
vector(_InputIterator __first, _InputIterator __last,
const allocator_type& __a = allocator_type())
: _Base(__a)
{
struct PseudoRange { _InputIterator begin(); _InputIterator end(); };
if constexpr (std::ranges::random_access_range<PseudoRange>) {
_M_range_initialize(__first, __last,
std::random_access_iterator_tag());
}
else if constexpr (std::ranges::forward_range<PseudoRange>) {
_M_range_initialize(__first, __last, std::forward_iterator_tag());
}
else {
_M_range_initialize(__first, __last,
std::__iterator_category(__first));
}
#else
...
#endif
-----
Here is a PoC:
#include <vector>
#include <ranges>
#include <iostream>
template<typename I>
void test(I first, I last) {
struct PseudoRange { I begin(); I end(); };
if constexpr (std::ranges::random_access_range<PseudoRange>) {
std::cout << "RA\n";
}
else if constexpr (std::ranges::forward_range<PseudoRange>) {
std::cout << "F\n";
}
else {
std::cout << "I\n";
}
}
int main() {
auto rng = std::ranges::iota_view{0, 10} | std::views::transform([](int i)
{ return i*i; });
test(rng.begin(), rng.end());
auto rng2 = std::ranges::iota_view{0, 10} | std::views::filter([](int i) {
return i%2; });
test(rng2.begin(), rng2.end());
return 0;
}