Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overloading bitshift operator in c++

I want to overload the bitshift operator for a uint32x4_t defined on ARM systems in arm_neon.h.

struct uint32x4_t {
   uint32_t val[4];
};

This should be done with a call to a SIMD function, which expects the value to shift and a constant immediate:

uint32x4_t simdShift(uint32x4_t, constant_immediate);

shift.h

#ifndef SHIFT_H
#define SHIFT_H

namespace A {
   namespace B {
      /*uint32x4_t simdLoad(uint32_t*) {
         ...
      }*/

      template<int N>
      uint32x4_t shiftRight(uint32x4_t vec) {
        return vshrq_n_u32(vec,N);
      }
   }
}
uint32x4_t operator>>(uint32x4_t const & vec, const int v) {
  return A::B::shiftRight<v>(vec);
}
#endif

main.cpp

#include "shift.h"

int main() {
   uint32_t* data = new uint32_t[4];
   data[0] = 1;
   data[1] = 2;
   data[2] = 3;
   data[3] = 4;
   uint32x4_t reg;// = simdLoad(data);
   reg = reg>>3;
   return 0;
}

This code produces the error:

‘uint32x4_t operator>>(const uint32x4_t&, int)’ must have an argument of class or enumerated type uint32x4_t operator>>(uint32x4_t const & vec, const int v) {

Is there a workaround to overload operator>> for "native" types like uint32x4_t?

Edit: I adapted the suggested workarounds, but the error still remains the same :(

like image 467
Hymir Avatar asked Dec 23 '22 20:12

Hymir


1 Answers

An incremental improvement on ErmIg's answer:

template<int N>
constexpr std::integral_constant<int, N> i_{};

template<int N>
uint32x4_t operator >>(uint32x4_t value, std::integral_constant<int, N>) noexcept {
    return _mm_slli_si128(value, N);
}

int main() {
    std::uint32_t data[4] = {1, 2, 3, 4};
    uint32x4_t reg;// = simdLoad(&data);
    reg = reg >> i_<3>;
}

N.b. I've put operator>> in the global namespace; if you want to put it in a different namespace, you'll need to bring the operator into scope before you use it.

like image 173
ildjarn Avatar answered Jan 04 '23 19:01

ildjarn