Home > Software design >  Match all GNU C SIMD vector extension types in clang/gcc
Match all GNU C SIMD vector extension types in clang/gcc

Time:11-15

The objective is to write a type trait with the following signature:

template<typename T>
struct is_vector : std::true_type / std::false_type

such that you can use is_vector<T>::value in SFINAE signatures. How do I properly detect whether a type is __attribute__((__vector_size(<some_vector_width>)) <some_built-in_type> in GCC/clang?

I looked through the LLVM documentation but couldn't see any built-ins to detect this. The GNU C documentation similarly only documents it as a C extension, not mentioning C .

The backup plan is to specialize the template for each permutation but that really doesn't sound nice.

CodePudding user response:

You could create a type trait to check if it's one of these vector types. It was a bit tricky finding a way to do it, but using one of the built-in functions that operates on the vectors seems to work.

In this gcc example, I use __builtin_convertvector to try to convert the vector type to the same vector type. If it's not a vector type, SFINAE will select the test() function that returns false_type. If it is one of the vector types, it'll select the test() function that returns true_type.

#include <type_traits>

template<class T>
struct is_vector {
    static std::false_type test(...);

    template<class B>
    static auto test(B) ->
        decltype(__builtin_convertvector(std::declval<B>(), B), std::true_type{});

    static constexpr bool value = decltype(test(std::declval<T>()))::value;
};

template<class T>
static constexpr bool is_vector_v = is_vector<T>::value;

Demo

  • Related