1 /* This file is part of the Vc library. {{{
2 Copyright © 2012-2015 Matthias Kretz <kretz@kde.org>
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are met:
6 * Redistributions of source code must retain the above copyright
7 notice, this list of conditions and the following disclaimer.
8 * Redistributions in binary form must reproduce the above copyright
9 notice, this list of conditions and the following disclaimer in the
10 documentation and/or other materials provided with the distribution.
11 * Neither the names of contributing organizations nor the
12 names of its contributors may be used to endorse or promote products
13 derived from this software without specific prior written permission.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
19 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
26 }}}*/
27
28 #include "unittest.h"
29 #include "virtest/vir/metahelpers.h"
30
31 using namespace Vc;
32
33 static_assert(!std::is_convertible< float_v, double_v>::value, "!std::is_convertible< float_v, double_v>");
34 static_assert(!std::is_convertible< int_v, double_v>::value, "!std::is_convertible< int_v, double_v>");
35 static_assert(!std::is_convertible< uint_v, double_v>::value, "!std::is_convertible< uint_v, double_v>");
36 static_assert(!std::is_convertible< short_v, double_v>::value, "!std::is_convertible< short_v, double_v>");
37 static_assert(!std::is_convertible<ushort_v, double_v>::value, "!std::is_convertible<ushort_v, double_v>");
38
39 static_assert(!std::is_convertible<double_v, float_v>::value, "!std::is_convertible<double_v, float_v>");
40 static_assert(!std::is_convertible< int_v, float_v>::value, "!std::is_convertible< int_v, float_v>");
41 static_assert(!std::is_convertible< uint_v, float_v>::value, "!std::is_convertible< uint_v, float_v>");
42 static_assert(!std::is_convertible< short_v, float_v>::value, "!std::is_convertible< short_v, float_v>");
43 static_assert(!std::is_convertible<ushort_v, float_v>::value, "!std::is_convertible<ushort_v, float_v>");
44
45 static_assert(!std::is_convertible<double_v, int_v>::value, "!std::is_convertible<double_v, int_v>");
46 static_assert(!std::is_convertible< float_v, int_v>::value, "!std::is_convertible< float_v, int_v>");
47 static_assert( std::is_convertible< uint_v, int_v>::value, " std::is_convertible< uint_v, int_v>");
48 static_assert(!std::is_convertible< short_v, int_v>::value, "!std::is_convertible< short_v, int_v>");
49 static_assert(!std::is_convertible<ushort_v, int_v>::value, "!std::is_convertible<ushort_v, int_v>");
50
51 static_assert(!std::is_convertible<double_v, uint_v>::value, "!std::is_convertible<double_v, uint_v>");
52 static_assert(!std::is_convertible< float_v, uint_v>::value, "!std::is_convertible< float_v, uint_v>");
53 static_assert( std::is_convertible< int_v, uint_v>::value, " std::is_convertible< int_v, uint_v>");
54 static_assert(!std::is_convertible< short_v, uint_v>::value, "!std::is_convertible< short_v, uint_v>");
55 static_assert(!std::is_convertible<ushort_v, uint_v>::value, "!std::is_convertible<ushort_v, uint_v>");
56
57 static_assert(!std::is_convertible<double_v, short_v>::value, "!std::is_convertible<double_v, short_v>");
58 static_assert(!std::is_convertible< float_v, short_v>::value, "!std::is_convertible< float_v, short_v>");
59 static_assert(!std::is_convertible< int_v, short_v>::value, "!std::is_convertible< int_v, short_v>");
60 static_assert(!std::is_convertible< uint_v, short_v>::value, "!std::is_convertible< uint_v, short_v>");
61 static_assert( std::is_convertible<ushort_v, short_v>::value, " std::is_convertible<ushort_v, short_v>");
62
63 static_assert(!std::is_convertible<double_v, ushort_v>::value, "!std::is_convertible<double_v, ushort_v>");
64 static_assert(!std::is_convertible< float_v, ushort_v>::value, "!std::is_convertible< float_v, ushort_v>");
65 static_assert(!std::is_convertible< int_v, ushort_v>::value, "!std::is_convertible< int_v, ushort_v>");
66 static_assert(!std::is_convertible< uint_v, ushort_v>::value, "!std::is_convertible< uint_v, ushort_v>");
67 static_assert( std::is_convertible< short_v, ushort_v>::value, " std::is_convertible< short_v, ushort_v>");
68
69 template <typename A, typename B, typename C>
70 Vc::enable_if<std::is_integral<A>::value && std::is_integral<B>::value, void>
integral_tests(A a,B b,C c)71 integral_tests(A a, B b, C c)
72 {
73 #if !defined(Vc_GCC) || Vc_GCC != 0x40801
74 // Skipping tests involving operator& because of a bug in GCC 4.8.1
75 // (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57532)
76 static_assert(std::is_same<decltype(a & b), C>::value, "incorrect return type deduction");
77 COMPARE(typeid(a & b), typeid(C));
78 #endif
79 static_assert(std::is_same<decltype(a | b), C>::value, "incorrect return type deduction");
80 static_assert(std::is_same<decltype(a ^ b), C>::value, "incorrect return type deduction");
81 COMPARE(typeid(a | b), typeid(C));
82 COMPARE(typeid(a ^ b), typeid(C));
83 }
84 template <typename A, typename B, typename C>
85 Vc::enable_if<!(std::is_integral<A>::value && std::is_integral<B>::value), void>
integral_tests(A,B,C)86 integral_tests(A, B, C)
87 {
88 }
89 #define _TYPE_TEST(a, b, c) \
90 { \
91 integral_tests(a(), b(), c()); \
92 using logical_return = typename std::conditional< \
93 std::is_fundamental<decltype(b())>::value, decltype(!a()), \
94 typename std::conditional<std::is_fundamental<decltype(a())>::value, \
95 decltype(!b()), c::Mask>::type>::type; \
96 COMPARE(typeid(a() && b()), typeid(logical_return)); \
97 COMPARE(typeid(a() || b()), typeid(logical_return)); \
98 COMPARE(typeid(a() * b()), typeid(c)); \
99 COMPARE(typeid(a() / b()), typeid(c)); \
100 COMPARE(typeid(a() + b()), typeid(c)); \
101 COMPARE(typeid(a() - b()), typeid(c)); \
102 COMPARE(typeid(a() == b()), typeid(c::Mask)); \
103 COMPARE(typeid(a() != b()), typeid(c::Mask)); \
104 COMPARE(typeid(a() <= b()), typeid(c::Mask)); \
105 COMPARE(typeid(a() >= b()), typeid(c::Mask)); \
106 COMPARE(typeid(a() < b()), typeid(c::Mask)); \
107 static_assert(std::is_same<decltype(a() && b()), logical_return>::value, #a " && " #b " => " #c); \
108 static_assert(std::is_same<decltype(a() || b()), logical_return>::value, #a " || " #b " => " #c); \
109 static_assert(std::is_same<decltype(a() * b()), c>::value, #a " * " #b " => " #c); \
110 static_assert(std::is_same<decltype(a() / b()), c>::value, #a " / " #b " => " #c); \
111 static_assert(std::is_same<decltype(a() + b()), c>::value, #a " + " #b " => " #c); \
112 static_assert(std::is_same<decltype(a() - b()), c>::value, #a " - " #b " => " #c); \
113 static_assert(std::is_same<decltype(a() == b()), c::Mask>::value, #a " == " #b " => " #c "::Mask"); \
114 static_assert(std::is_same<decltype(a() != b()), c::Mask>::value, #a " != " #b " => " #c "::Mask"); \
115 static_assert(std::is_same<decltype(a() <= b()), c::Mask>::value, #a " <= " #b " => " #c "::Mask"); \
116 static_assert(std::is_same<decltype(a() >= b()), c::Mask>::value, #a " >= " #b " => " #c "::Mask"); \
117 static_assert(std::is_same<decltype(a() < b()), c::Mask>::value, #a " < " #b " => " #c "::Mask"); \
118 }
119
120 #define TYPE_TEST(a, b, c) \
121 _TYPE_TEST(a, b, c) \
122 COMPARE(typeid(a() > b()), typeid(c::Mask))
123
124 template<typename T>
125 struct TestImplicitCast {
testTestImplicitCast126 static bool test(const T &) { return true; }
testTestImplicitCast127 static bool test( ... ) { return false; }
128 };
129
130 enum SomeEnum { EnumValue = 0 };
Enum()131 SomeEnum Enum() { return EnumValue; }
132
TEST(testImplicitTypeConversions)133 TEST(testImplicitTypeConversions)
134 {
135 VERIFY( TestImplicitCast< int>::test(double()));
136 VERIFY( TestImplicitCast< int>::test( float()));
137 VERIFY( TestImplicitCast< int>::test( Enum()));
138 VERIFY( TestImplicitCast< int>::test( short()));
139 VERIFY( TestImplicitCast< int>::test(ushort()));
140 VERIFY( TestImplicitCast< int>::test( char()));
141 VERIFY( TestImplicitCast< int>::test( uint()));
142 VERIFY( TestImplicitCast< int>::test( long()));
143 VERIFY( TestImplicitCast< int>::test( ulong()));
144 VERIFY( TestImplicitCast< int>::test( bool()));
145 VERIFY( TestImplicitCast<double_v>::test(double()));
146 VERIFY( TestImplicitCast<double_v>::test( float()));
147 VERIFY( TestImplicitCast<double_v>::test( int()));
148 VERIFY( TestImplicitCast< float_v>::test( float()));
149 VERIFY( TestImplicitCast< int_v>::test( int()));
150 VERIFY( TestImplicitCast< uint_v>::test( uint()));
151 VERIFY( TestImplicitCast< short_v>::test( short()));
152 VERIFY( TestImplicitCast<ushort_v>::test(ushort()));
153 VERIFY(!TestImplicitCast<double_v>::test(nullptr));
154 VERIFY(!TestImplicitCast< float_v>::test(nullptr));
155 VERIFY(!TestImplicitCast< int_v>::test(nullptr));
156 VERIFY(!TestImplicitCast< uint_v>::test(nullptr));
157 VERIFY(!TestImplicitCast< short_v>::test(nullptr));
158 VERIFY(!TestImplicitCast<ushort_v>::test(nullptr));
159
160 TYPE_TEST( double_v, double_v, double_v);
161 TYPE_TEST( double_v, double, double_v);
162 TYPE_TEST( double_v, float, double_v);
163 TYPE_TEST( double_v, short, double_v);
164 TYPE_TEST( double_v, ushort, double_v);
165 TYPE_TEST( double_v, int, double_v);
166 TYPE_TEST( double_v, uint, double_v);
167 TYPE_TEST( double_v, long, double_v);
168 TYPE_TEST( double_v, ulong, double_v);
169 TYPE_TEST( double_v, llong, double_v);
170 TYPE_TEST( double_v, ullong, double_v);
171 TYPE_TEST( double_v, Enum, double_v);
172 TYPE_TEST( double_v, bool, double_v);
173 TYPE_TEST( double, double_v, double_v);
174 TYPE_TEST( float, double_v, double_v);
175 TYPE_TEST( short, double_v, double_v);
176 TYPE_TEST( ushort, double_v, double_v);
177 TYPE_TEST( int, double_v, double_v);
178 TYPE_TEST( uint, double_v, double_v);
179 TYPE_TEST( long, double_v, double_v);
180 TYPE_TEST( ulong, double_v, double_v);
181 TYPE_TEST( llong, double_v, double_v);
182 TYPE_TEST( ullong, double_v, double_v);
183 TYPE_TEST( Enum, double_v, double_v);
184 TYPE_TEST( bool, double_v, double_v);
185 // double_v done
186
187 TYPE_TEST( float_v, float_v, float_v);
188 TYPE_TEST( float_v, float, float_v);
189 TYPE_TEST( float_v, short, float_v);
190 TYPE_TEST( float_v, ushort, float_v);
191 TYPE_TEST( float_v, int, float_v);
192 TYPE_TEST( float_v, uint, float_v);
193 TYPE_TEST( float_v, long, float_v);
194 TYPE_TEST( float_v, ulong, float_v);
195 TYPE_TEST( float_v, llong, float_v);
196 TYPE_TEST( float_v, ullong, float_v);
197 TYPE_TEST( float_v, Enum, float_v);
198 TYPE_TEST( float_v, bool, float_v);
199 TYPE_TEST( float, float_v, float_v);
200 TYPE_TEST( short, float_v, float_v);
201 TYPE_TEST( ushort, float_v, float_v);
202 TYPE_TEST( int, float_v, float_v);
203 TYPE_TEST( uint, float_v, float_v);
204 TYPE_TEST( long, float_v, float_v);
205 TYPE_TEST( ulong, float_v, float_v);
206 TYPE_TEST( llong, float_v, float_v);
207 TYPE_TEST( ullong, float_v, float_v);
208 TYPE_TEST( Enum, float_v, float_v);
209 TYPE_TEST( bool, float_v, float_v);
210 // double_v + float_v done
211
212 TYPE_TEST( short_v, short_v, short_v);
213 TYPE_TEST( short_v, short, short_v);
214 TYPE_TEST( short_v, ushort_v, ushort_v);
215 TYPE_TEST( short_v, ushort, ushort_v);
216 TYPE_TEST( short_v, int, short_v);
217 TYPE_TEST( short_v, uint, ushort_v);
218 TYPE_TEST( short_v, Enum, short_v);
219 TYPE_TEST( short_v, bool, short_v);
220 TYPE_TEST( short, short_v, short_v);
221 TYPE_TEST( ushort_v, short_v, ushort_v);
222 TYPE_TEST( ushort, short_v, ushort_v);
223 TYPE_TEST( int, short_v, short_v);
224 TYPE_TEST( uint, short_v, ushort_v);
225 TYPE_TEST( Enum, short_v, short_v);
226 TYPE_TEST( bool, short_v, short_v);
227
228 TYPE_TEST( ushort_v, short, ushort_v);
229 TYPE_TEST( ushort_v, ushort_v, ushort_v);
230 TYPE_TEST( ushort_v, ushort, ushort_v);
231 TYPE_TEST( ushort_v, int, ushort_v);
232 TYPE_TEST( ushort_v, uint, ushort_v);
233 TYPE_TEST( ushort_v, Enum, ushort_v);
234 TYPE_TEST( ushort_v, bool, ushort_v);
235 TYPE_TEST( short, ushort_v, ushort_v);
236 TYPE_TEST( ushort, ushort_v, ushort_v);
237 TYPE_TEST( int, ushort_v, ushort_v);
238 TYPE_TEST( uint, ushort_v, ushort_v);
239 TYPE_TEST( Enum, ushort_v, ushort_v);
240 TYPE_TEST( bool, ushort_v, ushort_v);
241
242 TYPE_TEST( int_v, ushort, int_v);
243 TYPE_TEST( int_v, short, int_v);
244 TYPE_TEST( int_v, int_v, int_v);
245 TYPE_TEST( int_v, int, int_v);
246 TYPE_TEST( int_v, uint_v, uint_v);
247 TYPE_TEST( int_v, uint, uint_v);
248 TYPE_TEST( int_v, Enum, int_v);
249 TYPE_TEST( int_v, bool, int_v);
250 TYPE_TEST( ushort, int_v, int_v);
251 TYPE_TEST( short, int_v, int_v);
252 TYPE_TEST( int, int_v, int_v);
253 TYPE_TEST( uint_v, int_v, uint_v);
254 TYPE_TEST( uint, int_v, uint_v);
255 TYPE_TEST( Enum, int_v, int_v);
256 TYPE_TEST( bool, int_v, int_v);
257
258 TYPE_TEST( uint_v, short, uint_v);
259 TYPE_TEST( uint_v, ushort, uint_v);
260 TYPE_TEST( uint_v, int_v, uint_v);
261 TYPE_TEST( uint_v, int, uint_v);
262 TYPE_TEST( uint_v, uint_v, uint_v);
263 TYPE_TEST( uint_v, uint, uint_v);
264 TYPE_TEST( uint_v, Enum, uint_v);
265 TYPE_TEST( uint_v, bool, uint_v);
266 TYPE_TEST( short, uint_v, uint_v);
267 TYPE_TEST( ushort, uint_v, uint_v);
268 TYPE_TEST( int_v, uint_v, uint_v);
269 TYPE_TEST( int, uint_v, uint_v);
270 TYPE_TEST( uint, uint_v, uint_v);
271 TYPE_TEST( Enum, uint_v, uint_v);
272 TYPE_TEST( bool, uint_v, uint_v);
273 }
274
275 struct Plus {
276 template <class L, class R>
277 decltype(std::declval<L>() + std::declval<R>()) operator()(L &&, R &&);
278 };
279 struct Xor {
280 template <class L, class R>
281 decltype(std::declval<L>() ^ std::declval<R>()) operator()(L &&, R &&);
282 };
283 struct Equal {
284 template <class L, class R>
285 decltype(std::declval<L>() == std::declval<R>()) operator()(L &&, R &&);
286 };
TEST_TYPES(Pair,failures,Typelist<Typelist<double_v,float_v>,Typelist<double_v,short_v>,Typelist<double_v,ushort_v>,Typelist<double_v,int_v>,Typelist<double_v,uint_v>,Typelist<float_v,double>,Typelist<float_v,short_v>,Typelist<float_v,ushort_v>,Typelist<int_v,float_v>,Typelist<int_v,float>,Typelist<int_v,double>,Typelist<int_v,long>,Typelist<int_v,llong>,Typelist<short_v,int_v>,Typelist<short_v,uint_v>,Typelist<short_v,float>,Typelist<ushort_v,int_v>,Typelist<ushort_v,uint_v>,Typelist<ushort_v,float>,Typelist<fixed_size_simd<int,3>,int_v>>)287 TEST_TYPES(Pair, failures, Typelist<
288 Typelist<double_v, float_v>,
289 Typelist<double_v, short_v>,
290 Typelist<double_v, ushort_v>,
291 Typelist<double_v, int_v>,
292 Typelist<double_v, uint_v>,
293 Typelist<float_v, double>,
294 Typelist<float_v, short_v>,
295 Typelist<float_v, ushort_v>,
296 Typelist<int_v, float_v>,
297 Typelist<int_v, float>,
298 Typelist<int_v, double>,
299 Typelist<int_v, long>,
300 Typelist<int_v, llong>,
301 Typelist<short_v, int_v>,
302 Typelist<short_v, uint_v>,
303 Typelist<short_v, float>,
304 Typelist<ushort_v, int_v>,
305 Typelist<ushort_v, uint_v>,
306 Typelist<ushort_v, float>,
307 Typelist<fixed_size_simd<int, 3>, int_v>
308 >)
309 {
310 using A = typename Pair::template at<0>;
311 using B = typename Pair::template at<1>;
312 VERIFY(!(vir::test::sfinae_is_callable<A, B>(Plus())));
313 VERIFY(!(vir::test::sfinae_is_callable<B, A>(Plus())));
314 VERIFY(!(vir::test::sfinae_is_callable<A, B>(Xor())));
315 VERIFY(!(vir::test::sfinae_is_callable<B, A>(Xor())));
316 VERIFY(!(vir::test::sfinae_is_callable<A, B>(Equal())));
317 VERIFY(!(vir::test::sfinae_is_callable<B, A>(Equal())));
318 }
319
320 // vim: foldmethod=marker
321