1 | /* Copyright (C) 2011-2014 Povilas Kanapickas <povilas@radix.lt> |
2 | |
3 | Distributed under the Boost Software License, Version 1.0. |
4 | (See accompanying file LICENSE_1_0.txt or copy at |
5 | http://www.boost.org/LICENSE_1_0.txt) |
6 | */ |
7 | |
8 | #ifndef LIBSIMDPP_SIMDPP_DETAIL_NOT_IMPLEMENTED_H |
9 | #define LIBSIMDPP_SIMDPP_DETAIL_NOT_IMPLEMENTED_H |
10 | |
11 | #ifndef LIBSIMDPP_SIMD_H |
12 | #error "This file must be included through simd.h" |
13 | #endif |
14 | |
15 | #include <simdpp/types.h> |
16 | #include <type_traits> |
17 | |
18 | namespace simdpp { |
19 | namespace SIMDPP_ARCH_NAMESPACE { |
20 | |
21 | namespace detail { |
22 | |
23 | /** A data type that can be implicitly converted to all types used in the |
24 | library. Used to silence 'no return value' warnings |
25 | */ |
26 | class dummy_value { |
27 | public: |
28 | template<unsigned N> operator int8<N>() { return int8<N>(); } |
29 | template<unsigned N> operator uint8<N>() { return uint8<N>(); } |
30 | template<unsigned N> operator mask_int8<N>() { return mask_int8<N>(); } |
31 | template<unsigned N> operator int16<N>() { return int16<N>(); } |
32 | template<unsigned N> operator uint16<N>() { return uint16<N>(); } |
33 | template<unsigned N> operator mask_int16<N>() { return mask_int16<N>(); } |
34 | template<unsigned N> operator int32<N>() { return int32<N>(); } |
35 | template<unsigned N> operator uint32<N>() { return uint32<N>(); } |
36 | template<unsigned N> operator mask_int32<N>() { return mask_int32<N>(); } |
37 | template<unsigned N> operator int64<N>() { return int64<N>(); } |
38 | template<unsigned N> operator uint64<N>() { return uint64<N>(); } |
39 | template<unsigned N> operator mask_int64<N>() { return mask_int64<N>(); } |
40 | template<unsigned N> operator float32<N>() { return float32<N>(); } |
41 | template<unsigned N> operator mask_float32<N>() { return mask_float32<N>(); } |
42 | template<unsigned N> operator float64<N>() { return float64<N>(); } |
43 | template<unsigned N> operator mask_float64<N>() { return mask_float64<N>(); } |
44 | |
45 | template<unsigned N> operator int8<N,expr_empty>() { return int8<N>(); } |
46 | template<unsigned N> operator uint8<N,expr_empty>() { return uint8<N>(); } |
47 | template<unsigned N> operator mask_int8<N,expr_empty>() { return mask_int8<N>(); } |
48 | template<unsigned N> operator int16<N,expr_empty>() { return int16<N>(); } |
49 | template<unsigned N> operator uint16<N,expr_empty>() { return uint16<N>(); } |
50 | template<unsigned N> operator mask_int16<N,expr_empty>() { return mask_int16<N>(); } |
51 | template<unsigned N> operator int32<N,expr_empty>() { return int32<N>(); } |
52 | template<unsigned N> operator uint32<N,expr_empty>() { return uint32<N>(); } |
53 | template<unsigned N> operator mask_int32<N,expr_empty>() { return mask_int32<N>(); } |
54 | template<unsigned N> operator int64<N,expr_empty>() { return int64<N>(); } |
55 | template<unsigned N> operator uint64<N,expr_empty>() { return uint64<N>(); } |
56 | template<unsigned N> operator mask_int64<N,expr_empty>() { return mask_int64<N>(); } |
57 | template<unsigned N> operator float32<N,expr_empty>() { return float32<N>(); } |
58 | template<unsigned N> operator mask_float32<N,expr_empty>() { return mask_float32<N>(); } |
59 | template<unsigned N> operator float64<N,expr_empty>() { return float64<N>(); } |
60 | template<unsigned N> operator mask_float64<N,expr_empty>() { return mask_float64<N>(); } |
61 | |
62 | operator int32_t() { return 0; } |
63 | operator uint32_t() { return 0; } |
64 | operator int64_t() { return 0; } |
65 | operator uint64_t() { return 0; } |
66 | operator float() { return 0; } |
67 | operator double() { return 0; } |
68 | }; |
69 | |
70 | } // namespace detail |
71 | |
72 | /** Causes compile-time error whenever unimplemented functionality is used. |
73 | The function may only be used in templates which are not instantiated by |
74 | default. |
75 | */ |
76 | template<class T> |
77 | void libsimdpp_instruction_not_available_template() |
78 | { |
79 | static_assert(!std::is_same<T, T>::value, "The instruction is not available" ); |
80 | } |
81 | |
82 | /** Causes linker error whenever unimplemented functionality is used. Compared |
83 | to libsimdpp_instruction_not_available, this function is not limited to |
84 | template contexts, but the errors are much harder to track down. |
85 | */ |
86 | void libsimdpp_instruction_not_available0(); |
87 | void libsimdpp_instruction_not_available1(); |
88 | void libsimdpp_instruction_not_available2(); |
89 | void libsimdpp_instruction_not_available3(); |
90 | void libsimdpp_instruction_not_available4(); |
91 | |
92 | #define SIMDPP_NOT_IMPLEMENTED_TEMPLATE0(T) ( \ |
93 | libsimdpp_instruction_not_available_template<T>(), \ |
94 | ::simdpp::SIMDPP_ARCH_NAMESPACE::detail::dummy_value() \ |
95 | ) |
96 | |
97 | #define SIMDPP_NOT_IMPLEMENTED_TEMPLATE1(T,A) ( \ |
98 | (void) A, \ |
99 | libsimdpp_instruction_not_available_template<T>(), \ |
100 | ::simdpp::SIMDPP_ARCH_NAMESPACE::detail::dummy_value() \ |
101 | ) |
102 | |
103 | #define SIMDPP_NOT_IMPLEMENTED_TEMPLATE2(T,A,B) ( \ |
104 | (void) A, (void) B, \ |
105 | libsimdpp_instruction_not_available_template<T>(), \ |
106 | ::simdpp::SIMDPP_ARCH_NAMESPACE::detail::dummy_value() \ |
107 | ) |
108 | |
109 | #define SIMDPP_NOT_IMPLEMENTED_TEMPLATE3(T,A,B,C) ( \ |
110 | (void) A, (void) B, (void) C, \ |
111 | libsimdpp_instruction_not_available_template<T>(), \ |
112 | ::simdpp::SIMDPP_ARCH_NAMESPACE::detail::dummy_value() \ |
113 | ) |
114 | |
115 | #define SIMDPP_NOT_IMPLEMENTED_TEMPLATE4(T,A,B,C,D) ( \ |
116 | (void) A, (void) B, (void) C, (void) D, \ |
117 | libsimdpp_instruction_not_available_template<T>(), \ |
118 | ::simdpp::SIMDPP_ARCH_NAMESPACE::detail::dummy_value() \ |
119 | ) |
120 | |
121 | #define SIMDPP_NOT_IMPLEMENTED0() ( \ |
122 | libsimdpp_instruction_not_available0(), \ |
123 | ::simdpp::SIMDPP_ARCH_NAMESPACE::detail::dummy_value() \ |
124 | ) |
125 | |
126 | #define SIMDPP_NOT_IMPLEMENTED1(A) ( \ |
127 | (void) A, \ |
128 | libsimdpp_instruction_not_available1(), \ |
129 | ::simdpp::SIMDPP_ARCH_NAMESPACE::detail::dummy_value() \ |
130 | ) |
131 | |
132 | #define SIMDPP_NOT_IMPLEMENTED2(A,B) ( \ |
133 | (void) A, (void) B, \ |
134 | libsimdpp_instruction_not_available2(), \ |
135 | ::simdpp::SIMDPP_ARCH_NAMESPACE::detail::dummy_value() \ |
136 | ) |
137 | |
138 | #define SIMDPP_NOT_IMPLEMENTED3(A,B,C) ( \ |
139 | (void) A, (void) B, (void) C, \ |
140 | libsimdpp_instruction_not_available3(), \ |
141 | ::simdpp::SIMDPP_ARCH_NAMESPACE::detail::dummy_value() \ |
142 | ) |
143 | |
144 | #define SIMDPP_NOT_IMPLEMENTED4(A,B,C,D) ( \ |
145 | (void) A, (void) B, (void) C, (void) D, \ |
146 | libsimdpp_instruction_not_available4(), \ |
147 | ::simdpp::SIMDPP_ARCH_NAMESPACE::detail::dummy_value() \ |
148 | ) |
149 | |
150 | } // namespace SIMDPP_ARCH_NAMESPACE |
151 | } // namespace simdpp |
152 | |
153 | #endif |
154 | |