- 
          
 - 
                Notifications
    
You must be signed in to change notification settings  - Fork 194
 
Open
Description
The following fails to compile starting from gcc 14.3 (godbolt link):
#include <immer/map.hpp>
#include <unordered_map>
#include <vector>
int main()
{
    auto um = std::unordered_map<int,int>{ {0,0}, {1,1}, {2,2} };
    auto uv = std::vector<std::pair<int,int>>(um.begin(), um.end());
    static_assert(!std::sized_sentinel_for<decltype(um.end()), decltype(um.begin())>);
    auto im = immer::map<int,int>{ {0,0}, {1,1}, {2,2} };
    auto iv = std::vector<std::pair<int,int>>(im.begin(), im.end());
    static_assert(std::sized_sentinel_for<decltype(im.end()), decltype(im.begin())>);
    return 0; 
}with the following:
/opt/compiler-explorer/gcc-14.3.0/include/c++/14.3.0/bits/ranges_base.h:961:23:   required from 'constexpr std::iter_difference_t<typename std::decay<_Tp>::type> std::ranges::__distance_fn::operator()(_It&&, _Sent) const [with _It = immer::detail::hamts::champ_iterator<std::pair<int, int>, immer::map<int, int>::hash_key, immer::map<int, int>::equal_key, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap>, immer::refcount_policy, immer::spinlock_policy>, 5>&; _Sent = immer::detail::hamts::champ_iterator<std::pair<int, int>, immer::map<int, int>::hash_key, immer::map<int, int>::equal_key, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap>, immer::refcount_policy, immer::spinlock_policy>, 5>; std::iter_difference_t<typename std::decay<_Tp>::type> = long int; typename std::decay<_Tp>::type = immer::detail::hamts::champ_iterator<std::pair<int, int>, immer::map<int, int>::hash_key, immer::map<int, int>::equal_key, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap>, immer::refcount_policy, immer::spinlock_policy>, 5>]'
  961 |       { return __last - static_cast<const decay_t<_It>&>(__first); }
      |                ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-14.3.0/include/c++/14.3.0/bits/stl_vector.h:718:44:   required from 'constexpr std::vector<_Tp, _Alloc>::vector(_InputIterator, _InputIterator, const allocator_type&) [with _InputIterator = immer::detail::hamts::champ_iterator<std::pair<int, int>, immer::map<int, int>::hash_key, immer::map<int, int>::equal_key, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap>, immer::refcount_policy, immer::spinlock_policy>, 5>; <template-parameter-2-2> = void; _Tp = std::pair<int, int>; _Alloc = std::allocator<std::pair<int, int> >; allocator_type = std::allocator<std::pair<int, int> >]'
  718 |                 = static_cast<size_type>(ranges::distance(__first, __last));
      |                                          ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~
<source>:12:67:   required from here
   12 |     auto iv = std::vector<std::pair<int,int>>(im.begin(), im.end());
      |                                                                   ^
/opt/compiler-explorer/libs/immer/trunk/immer/detail/iterator_facade.hpp:172:23: error: static assertion failed
  172 |         static_assert(is_random_access, "");
but the equivalent code for a std::unordered_map works.
The problem might be that immer::map/set have iterator pairs for which std::sized_sentinel_for is satisfied. This then causes the wrong implementation of std::ranges::distance to be selected at compile time.
Note that both the iterators for std::unordered_map and immer::map are forward_iterator.
This is likely to affect many std::ranges::* function. For instance std::ranges::copy(im, iv) also fails to compile for the same reason.
Metadata
Metadata
Assignees
Labels
No labels