Issue 127095
Summary libcxx error global operator <=> for std::set has only two template parameters(_Key, _Allocator) but need tree(_Key, Compare, Allocator)
Labels libc++
Assignees
Reporter leanid
    Problem:
current libc++ include next std::set operator<=> for c++20
```cpp
template <class _Key, class _Allocator>
_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Key>
operator<=>(const set<_Key, _Allocator>& __x, const set<_Key, _Allocator>& __y) {
  return std::lexicographical_compare_three_way(
      __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Key, _Key>);
}
```
If we add custom allocator and custom comparator we need operator<=> with three template parameters like:
```cpp
namespace std
{
// we need three template parameters to find this if using custom _Allocator
template <class _Key, class Comparator, class _Allocator>
auto operator<=>(const set<_Key, Comparator, _Allocator>& __x,
                 const set<_Key, Comparator, _Allocator>& __y)
{
    return std::lexicographical_compare_three_way(
 __x.begin(),
        __x.end(),
        __y.begin(),
 __y.end(),
        std::__synth_three_way<_Key, _Key>);
}
} // namespace std
```
Minimal reproduction:
**main.cxx** file:
```cpp
#include <cstdlib>
#include <functional>
#include <iostream>
#include <set>

struct my_type
{
    int  i;
    bool operator<(const my_type& other) const { return i < other.i; }
};

template <class T> class MyAllocator
{
public:
    using value_type                             = T;
    using size_type                              = std::size_t;
 using difference_type                        = std::ptrdiff_t;
    using propagate_on_container_move_assignment = std::true_type;

    T* allocate(size_type n, const void* hint = 0)
    {
        std::cout << "Alloc" << n << std::endl;
        return static_cast<T*>(malloc(n * sizeof(T)));
    }

    void      deallocate(T* p, size_type n) { free(p); }
    size_type max_size() const
    {
        return size_type(std::numeric_limits<unsigned int>::max() / sizeof(T));
    }
 void construct(T* p, const T& value) { _construct(p, value); }
    void destroy(T* p) { _destroy(p); }
};

template <class T, class U>
bool operator==(const MyAllocator<T>&, const MyAllocator<U>&) noexcept
{
 return true;
}

template <class T, class U>
bool operator!=(const MyAllocator<T>&, const MyAllocator<U>&) noexcept
{
    return false;
}

#if defined(FIX_LIBCXX) // 1 to fix error
namespace std
{
// we need three template parameters to find this if using custom _Allocator
template <class _Key, class Comparator, class _Allocator>
auto operator<=>(const set<_Key, Comparator, _Allocator>& __x,
 const set<_Key, Comparator, _Allocator>& __y)
{
    return std::lexicographical_compare_three_way(
        __x.begin(),
 __x.end(),
        __y.begin(),
        __y.end(),
 std::__synth_three_way<_Key, _Key>);
}
} // namespace std
#endif

int main()
{
    std::set<my_type> s01;
    std::set<my_type> s02;
 std::cout << "(s01 < s02): " << (s01 < s02) << std::endl; // compiles

 std::set<my_type, std::less<my_type>> s11;
    std::set<my_type, std::less<my_type>> s12;

    std::cout << "(s11 < s12): " << (s11 < s12) << std::endl; // compiles

    std::set<my_type, std::less<my_type>, std::allocator<my_type>> s21;
    std::set<my_type, std::less<my_type>, std::allocator<my_type>> s22;

    std::cout << "(s21 < s22): " << (s21 < s22) << std::endl; // compiles

    std::set<my_type, std::less<my_type>, MyAllocator<my_type>> s31;
    std::set<my_type, std::less<my_type>, MyAllocator<my_type>> s32;

    std::cout << "(s31 < s32): " << (s31 < s32) << std::endl; // error
    return EXIT_SUCCESS;
}
```
How to test it in terminal:
1. install latest libcxx or just install **XCode16.2**
2. in terminal go to directory with main.cxx file
3. to get error exec:> `clang++ -std=c++20 -stdlib=libc++ ./main.cxx`
4. to get fix exec:> `clang++ -std=c++20 -stdlib=libc++ -DFIX_LIBCXX ./main.cxx`

_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to