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;
}

Reply via email to