Closed t-sakashita closed 4 years ago
template <typename T>
using Complex = T[2];
template <typename T>
Complex<T>* elpa_complex_cast(std::complex<T>* c) {
return &reinterpret_cast<T(&)[2]>(*c);
}
clang++では、コンパイルエラー
/Users/sakashitatatsuya/development/rokko/rokko/elpa.hpp:63:3: error: no matching function for call to
'elpa_eigenvectors_dc'
elpa_eigenvectors_dc(handle, elpa_complex_cast(a), ev, complex_cast(q), &error);
^~~~~~~~~~~~~~~~~~~~
/Users/sakashitatatsuya/rokko/elpa/elpa-2020.05.001-1/Debug/include/elpa_openmp-2020.05.001/elpa/elpa_generated.h:140:7: note:
candidate function not viable: no known conversion from 'Complex<double> *' (aka 'double (*)[2]') to
'_Complex double *' for 2nd argument
void elpa_eigenvectors_dc(elpa_t handle, double complex *a, double *ev, double complex *q, int *error);
^
1 error generated.
clang++のC99では、_Complexが用いられる。
C言語のみでラッパーを書く方法を検討する。
template <typename T>
struct complex_type_traits {
using type = T;
};
template <>
struct complex_type_traits<double> {
using type = __complex__ double;
};
template <>
struct complex_type_traits<float> {
using type = __complex__ float;
};
template<typename T>
using Complex = typename complex_type_traits<T>::type;
template <typename T>
Complex<T>* elpa_complex_cast(std::complex<T>* c) {
return reinterpret_cast<Complex<T>*>(c);
}
キーワード__complex__
は、GNU互換機能である。
https://www.ibm.com/support/knowledgecenter/ja/SSXVZZ_16.1.0/com.ibm.xlcpp161.lelinux.doc/language_ref/gcc_exts_both.html
以下でも、コンパイルが通ることを確認した。GNU互換機能のためのオプションは不要であった。
オーバーロードに書き換えた。エイリアステンプレートは不要。
inline auto elpa_complex_cast(std::complex<double>* c) {
return reinterpret_cast<__complex__ double*>(c);
}
inline auto elpa_complex_cast(std::complex<float>* c) {
return reinterpret_cast<__complex__ float*>(c);
}
const版も不要。
2f891652075159a991396e1536d9c5bb14a227f1