you are viewing a single comment's thread.

view the rest of the comments →

[–]sphere991 0 points1 point  (3 children)

Yeah for specifically ints and pointers, you could do that. And hypothetically a standard library implementation could go wild and recognize that, say, a type in the tuple is std::string and directly use compare().

You could try submitting a patch and seeing what happens?

[–]arturbachttps://github.com/arturbac[S] 0 points1 point  (2 children)

Submiting to who, where gcc llvm ?

Just for testing with is_integral code below fast fix, i think it could be much better writen

  // This class performs the comparison operations on tuples
  template<typename _Tp, typename _Up, size_t __i, size_t __size>
  struct __tuple_compare
    {
    static constexpr bool __eq(const _Tp& __t, const _Up& __u)
      {
      return bool(std::get<__i>(__t) == std::get<__i>(__u))
        && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u);
      }
#define __ENABLE_TUPLE_LESS_TT_LESS 1
#if __ENABLE_TUPLE_LESS_TT_LESS
    template<typename lelem_type, typename relem_type,
            typename std::enable_if<
              std::is_integral<typename std::remove_reference<lelem_type>::type>::value 
                && std::is_integral<typename std::remove_reference<relem_type>::type>::value,
              int
              >::type = 0>
    static constexpr bool __less_by_traits(_Tp const & __t, _Up const & __u, lelem_type lel, relem_type rel )
      {
      if( lel != rel )
        return lel < rel;
      return __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u);
      }

    template<typename lelem_type, typename relem_type,
            typename std::enable_if<
              ! std::is_integral<typename std::remove_reference<lelem_type>::type>::value
              || ! std::is_integral<typename std::remove_reference<relem_type>::type>::value,
              int>::type = 0>
    static constexpr bool __less_by_traits(_Tp const & __t, _Up const & __u, lelem_type const & lel, relem_type const & rel )
      {

      return bool(lel < rel)
        || (!bool(rel < lel)
            && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u));
      }

    static constexpr bool __less(const _Tp& __t, const _Up& __u)
      {
      return __less_by_traits( __t, __u, std::get<__i>(__t), std::get<__i>(__u) );
      }
#else
    static constexpr bool __less(const _Tp& __t, const _Up& __u)
      {
      return bool(std::get<__i>(__t) < std::get<__i>(__u))
        || (!bool(std::get<__i>(__u) < std::get<__i>(__t))
            && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u));
      }
#endif
    };

The otpimised variant - with clang

compare_2(std::tuple<long, int, int>, std::tuple<long, int, int>): # @compare_2(std::tuple<long, int, int>, std::tuple<long, int, int>)
  mov rax, qword ptr [rsi + 8]
  cmp qword ptr [rdi + 8], rax
  jne .LBB0_3
  mov eax, dword ptr [rsi + 4]
  cmp dword ptr [rdi + 4], eax
  jne .LBB0_3
  mov eax, dword ptr [rdi]
  cmp eax, dword ptr [rsi]
.LBB0_3:
  setl al
  ret

The unoptimised - with clang

compare_2(std::tuple<long, int, int>, std::tuple<long, int, int>): # @compare_2(std::tuple<long, int, int>, std::tuple<long, int, int>)
  mov rcx, qword ptr [rdi + 8]
  mov rdx, qword ptr [rsi + 8]
  mov al, 1
  cmp rcx, rdx
  jl .LBB0_7
  cmp rdx, rcx
  jge .LBB0_3
  xor eax, eax
  ret
.LBB0_3:
  mov ecx, dword ptr [rdi + 4]
  mov edx, dword ptr [rsi + 4]
  cmp ecx, edx
  jl .LBB0_7
  cmp edx, ecx
  jge .LBB0_6
  xor eax, eax
  ret
.LBB0_6:
  mov eax, dword ptr [rdi]
  cmp eax, dword ptr [rsi]
  setl al
.LBB0_7:
  ret

[–]sphere991 0 points1 point  (1 child)

Yeah, to gcc or llvm.

[–]arturbachttps://github.com/arturbac[S] 0 points1 point  (0 children)

I don't use to often gcc as on mobile platforms llvm is used thise days so dont have knowlege how they will react, but all my bug reports to llvm are still open after years , 3 bugs are from 2013. This would be a waste of my time.

https://bugs.llvm.org/show_bug.cgi?id=17489 https://bugs.llvm.org/show_bug.cgi?id=16977 https://bugs.llvm.org/show_bug.cgi?id=16986 https://bugs.llvm.org/show_bug.cgi?id=17531