1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include <assert.h>
10 #include <cmath>
11 #include <cstdint>
12 #include <type_traits>
13 
14 #include "test_macros.h"
15 
16 template<class T>
17 struct correct_size_int
18 {
19     typedef typename std::conditional<sizeof(T) < sizeof(int), int, T>::type type;
20 };
21 
22 template <class Source, class Result>
23 void test_abs()
24 {
25     Source neg_val = -5;
26     Source pos_val = 5;
27     Result res = 5;
28 
29     ASSERT_SAME_TYPE(decltype(std::abs(neg_val)), Result);
30 
31     assert(std::abs(neg_val) == res);
32     assert(std::abs(pos_val) == res);
33 }
34 
35 void test_big()
36 {
37     long long int big_value = std::numeric_limits<long long int>::max(); // a value to big for ints to store
38     long long int negative_big_value = -big_value;
39     assert(std::abs(negative_big_value) == big_value); // make sure it doesnt get casted to a smaller type
40 }
41 
42 // The following is helpful to keep in mind:
43 // 1byte == char <= short <= int <= long <= long long
44 
45 int main(int, char**)
46 {
47     // On some systems char is unsigned.
48     // If that is the case, we should just test signed char twice.
49     typedef typename std::conditional<
50         std::is_signed<char>::value, char, signed char
51     >::type SignedChar;
52 
53     // All types less than or equal to and not greater than int are promoted to int.
54     test_abs<short int, int>();
55     test_abs<SignedChar, int>();
56     test_abs<signed char, int>();
57 
58     // These three calls have specific overloads:
59     test_abs<int, int>();
60     test_abs<long int, long int>();
61     test_abs<long long int, long long int>();
62 
63     // Here there is no guarantee that int is larger than int8_t so we
64     // use a helper type trait to conditional test against int.
65     test_abs<std::int8_t, typename correct_size_int<std::int8_t>::type>();
66     test_abs<std::int16_t, typename correct_size_int<std::int16_t>::type>();
67     test_abs<std::int32_t, typename correct_size_int<std::int32_t>::type>();
68     test_abs<std::int64_t, typename correct_size_int<std::int64_t>::type>();
69 
70     test_abs<long double, long double>();
71     test_abs<double, double>();
72     test_abs<float, float>();
73 
74     test_big();
75 
76     return 0;
77 }
78 
79