<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/127095>127095</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            libcxx error global operator <=> for std::set has only two template parameters(_Key, _Allocator) but need tree(_Key, Compare, Allocator)
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            libc++
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          leanid
      </td>
    </tr>
</table>

<pre>
    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`

</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzsWFtv47oR_jX0C7GGRMW3Bz84dowTtIsuulkgbwItjW2eUqRAUondX18Mqasvuzm7Pe3LMQQk0gyHMx8_zgzJrRUHBbAkk0cy2Yx45Y7aLCVwJfLRTufn5RejdxIKkqxItMoqY0A5KsUuI-yRsEcqVCarHKiCk6PW5aiYrCw4qksw3GlDkjVJNiR5onttaD2ORSRakWkUnqwsSbRyUJSSO6AkWWeSW0vTv8GZsDWt31ZS6iyYfCLRKv378-P6y5f0t-fNU7r95z8-p6vHZ5qm9qzcMXVHA5C-83NqwFbSkWTtzfmhV74RNs-0so5aaDXZ-mJKNqVpevIOfUz3TNiCktkjiVaUGnCVUR1GEk4i0wfDy6PIuEwzXZTcQOc4YXM_EH9pehrv4CAUfmQLP196GoPK-x_O1zrnoU47-xVM_UhqnNiCJOg7mW36q0Wi1fOevgPleU6zyjpdUN7ETrlqP4aI_Nd3ZAjkN0jxLtyRei9oSwAcVYADY6kU_4JAvgu2KF6ALXkGPiZ00rvKtoRt2-nu23Wa7oVCDWGp2NPKCnVoHO8t5Y9puW6jvE9VXjl9Hfsd0g0N3qFgy4ze76eMIUdb-NDKz_L0mqI9Hy_JOhBd0jZYO98b8Cscnm1oTZEr_vTo_VkoUXBJDZRG51XmhFY1CRk-BRdqnJ1O4Y3uhbzNUcKSJj8ieazLpdgFRgxF-0r5Sbi8JRXaOgO8uCXzq-0_RyvrTJU5WpxTdy5hsKhCOUpFgALfd1rLASEbKjaD2ZRqdwSDGSxIyOyx4YbAmYN8jEZpi24N9q1d84K7Pfz7-dzfYMHLstpJkQUY0cOwId-4rMB7dMX2_o8kG7T_OBhrxb8_MNSP7QqXH1NbCmZysd-DAZV939jATOkMDmsttT6VRpf8wB2kWqWZVo4LBSYt9BukoRoXWGAHxpypIWjBRXsvyLw67QJh8y5a1VWoNy1y1DuK2mgUdrt3uCXHYFNlukLVNa4wYcwvFGGs-aSaf9oBoHLZhTnIINyJLM24xYSE_oacV_Bgc64o-oaO6z1h8xe_0xftlg1ObrqQMZowQw69yD0Spa9ufQx85aV7A6hTBqu1PR9wq1vwU4pvIdcE5G5i1MTVjETUGxRUVYARWSpFIZwlybpSvrfKceth3F6r4Kd6FkxBV5FfhB0C9v7gxh6EGtb3Bfep3yNNvGlf3Ws24mH43nQO1hl97hmujXSCIXA_2uFtAfwWktJFmtng02SafhJAeviC1IU2FH9rxAuqNJwyKF2X3-p1wX0ySPY_4yOL_xwfO_rsubSXfmJO39Mc9kIB1rzt86vvbl9fa64gXeLQtJwoGOMT518t0P-55ek1N7c6mD_Y8vSEl-P-pJaHJaBysQ8cxBKBjU09cR-f_rmOJOumR0ieqI3iLmt9T43VavfqDObSKPZ9BSpjDCvaqztX8nt1qAkW10xIsHX5uONb_0gkwdqB297z-McBfsAIG9Tu74EQ10HGd0AYyP8gCD8bQl_KexnvIkr2q1B9dJ6Po8lqtNgdNAfy_x2aw8JxEV7yX4Dx-xN8HL-kxie5g99A_iP8mrrVS7lPr88v6ddv6_XT16_3Lht-0-9YqxxYR4WjQlEHphD-sIQxxGMqlHVcSopFyob7qdOJakN_r3BQLQ3Htde1ziGejll4JdGKjftG6UHjdLkwkDltzuGGojnyhcNetErGqHQAF6KicAJ_eEmeKB7_JFeH-obsk4dj0158-Q_-HLjp3aONCdu2x0of9kM7g6_5v2j_06brKW5MNsqXSb5IFnwEy3iWLB6mk9lsOjouk2ye54v5dPKQPMSzmM9ZnsfT-X6-yCbzJOcjsWQRm0QsTuLpZBpPx_ksydjDHHbRJJnN2Zw8RFBwIcdSvhVjbQ4jYW0Fy5jNosVkJPkOpPU3kIx1DiP_JpuRWeKoT7vqYMlDJIV1trPjhJOwrBc7LMNB6h3v2jk6vHwc3E8euaVayTN17_pWf0TY_MbVHlvQXeXq1iqcLYZ9h9-cff1RZeTy6FxpcW6_Ew7CHavdONMFYVsMp_7zqTT6d8DWfesxsoRta5jeluw_AQAA__9u1GsM">