xref: /llvm-project/libcxx/test/std/numerics/c.math/abs.pass.cpp (revision f54e7b4e3a131f74006682387469bda0a2377bbf)
16585f018SZoe Carver //===----------------------------------------------------------------------===//
26585f018SZoe Carver //
36585f018SZoe Carver // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
46585f018SZoe Carver // See https://llvm.org/LICENSE.txt for license information.
56585f018SZoe Carver // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66585f018SZoe Carver //
76585f018SZoe Carver //===----------------------------------------------------------------------===//
86585f018SZoe Carver 
96585f018SZoe Carver #include <assert.h>
106585f018SZoe Carver #include <cmath>
116585f018SZoe Carver #include <cstdint>
12b2e3c83bSCasey Carter #include <limits>
136585f018SZoe Carver #include <type_traits>
146585f018SZoe Carver 
156585f018SZoe Carver #include "test_macros.h"
166585f018SZoe Carver 
176585f018SZoe Carver template<class T>
186585f018SZoe Carver struct correct_size_int
196585f018SZoe Carver {
2080ddfcb5SZoe Carver     typedef typename std::conditional<sizeof(T) < sizeof(int), int, T>::type type;
216585f018SZoe Carver };
226585f018SZoe Carver 
236585f018SZoe Carver template <class Source, class Result>
test_abs()246585f018SZoe Carver void test_abs()
256585f018SZoe Carver {
266585f018SZoe Carver     Source neg_val = -5;
276585f018SZoe Carver     Source pos_val = 5;
286585f018SZoe Carver     Result res = 5;
296585f018SZoe Carver 
306585f018SZoe Carver     ASSERT_SAME_TYPE(decltype(std::abs(neg_val)), Result);
316585f018SZoe Carver 
326585f018SZoe Carver     assert(std::abs(neg_val) == res);
336585f018SZoe Carver     assert(std::abs(pos_val) == res);
346585f018SZoe Carver }
356585f018SZoe Carver 
test_big()366585f018SZoe Carver void test_big()
376585f018SZoe Carver {
38437e0e51SStephan T. Lavavej     long long int big_value = std::numeric_limits<long long int>::max(); // a value too big for ints to store
396585f018SZoe Carver     long long int negative_big_value = -big_value;
40437e0e51SStephan T. Lavavej     assert(std::abs(negative_big_value) == big_value); // make sure it doesn't get casted to a smaller type
416585f018SZoe Carver }
426585f018SZoe Carver 
4380ddfcb5SZoe Carver // The following is helpful to keep in mind:
4480ddfcb5SZoe Carver // 1byte == char <= short <= int <= long <= long long
4580ddfcb5SZoe Carver 
main(int,char **)466585f018SZoe Carver int main(int, char**)
476585f018SZoe Carver {
4886d560ffSZoe Carver     // On some systems char is unsigned.
4986d560ffSZoe Carver     // If that is the case, we should just test signed char twice.
50*f54e7b4eSLouis Dionne     typedef std::conditional<
5186d560ffSZoe Carver         std::is_signed<char>::value, char, signed char
5286d560ffSZoe Carver     >::type SignedChar;
5386d560ffSZoe Carver 
5480ddfcb5SZoe Carver     // All types less than or equal to and not greater than int are promoted to int.
5580ddfcb5SZoe Carver     test_abs<short int, int>();
5680ddfcb5SZoe Carver     test_abs<SignedChar, int>();
5780ddfcb5SZoe Carver     test_abs<signed char, int>();
586585f018SZoe Carver 
5980ddfcb5SZoe Carver     // These three calls have specific overloads:
6080ddfcb5SZoe Carver     test_abs<int, int>();
6180ddfcb5SZoe Carver     test_abs<long int, long int>();
6280ddfcb5SZoe Carver     test_abs<long long int, long long int>();
636585f018SZoe Carver 
6480ddfcb5SZoe Carver     // Here there is no guarantee that int is larger than int8_t so we
6580ddfcb5SZoe Carver     // use a helper type trait to conditional test against int.
66*f54e7b4eSLouis Dionne     test_abs<std::int8_t, correct_size_int<std::int8_t>::type>();
67*f54e7b4eSLouis Dionne     test_abs<std::int16_t, correct_size_int<std::int16_t>::type>();
68*f54e7b4eSLouis Dionne     test_abs<std::int32_t, correct_size_int<std::int32_t>::type>();
69*f54e7b4eSLouis Dionne     test_abs<std::int64_t, correct_size_int<std::int64_t>::type>();
706585f018SZoe Carver 
716585f018SZoe Carver     test_abs<long double, long double>();
726585f018SZoe Carver     test_abs<double, double>();
736585f018SZoe Carver     test_abs<float, float>();
746585f018SZoe Carver 
756585f018SZoe Carver     test_big();
766585f018SZoe Carver 
776585f018SZoe Carver     return 0;
786585f018SZoe Carver }
79