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