]>
Commit | Line | Data |
---|---|---|
a945c346 | 1 | // Copyright (C) 2015-2024 Free Software Foundation, Inc. |
3c219134 JW |
2 | // |
3 | // This file is part of the GNU ISO C++ Library. This library is free | |
4 | // software; you can redistribute it and/or modify it under the | |
5 | // terms of the GNU General Public License as published by the | |
6 | // Free Software Foundation; either version 3, or (at your option) | |
7 | // any later version. | |
8 | ||
9 | // This library is distributed in the hope that it will be useful, | |
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | // GNU General Public License for more details. | |
13 | ||
14 | // You should have received a copy of the GNU General Public License along | |
15 | // with this library; see the file COPYING3. If not see | |
16 | // <http://www.gnu.org/licenses/>. | |
17 | ||
18 | // { dg-do run { target c++17 } } | |
19 | ||
20 | #include <numeric> | |
21 | #include <climits> | |
22 | #include <testsuite_hooks.h> | |
23 | ||
24 | constexpr struct testcase { unsigned long long p, q, r; } testcases[] = { | |
25 | { 5, 8, 1 }, | |
26 | { 6, 35, 1 }, | |
27 | { 30, 42, 6 }, | |
28 | { 24, 60, 12 }, | |
29 | { 55, 144, 1 }, | |
30 | { 105, 252, 21 }, | |
31 | { 253, 22121, 11 }, | |
32 | { 1386, 3213, 63 }, | |
33 | { 2028, 2049, 3 }, | |
34 | { 46391, 62527, 2017 }, | |
35 | { 63245986, 39088169, 1 }, | |
36 | { 77160074263, 47687519812, 1 }, | |
37 | { 77160074264, 47687519812, 4 }, | |
38 | }; | |
39 | ||
40 | template<typename P, typename Q> | |
41 | constexpr bool | |
42 | check(P p, Q q, unsigned long long r) | |
43 | { | |
44 | using R = std::common_type_t<P, Q>; | |
45 | static_assert( std::is_same_v<decltype(std::gcd(p, q)), R> ); | |
46 | static_assert( std::is_same_v<decltype(std::gcd(q, p)), R> ); | |
47 | R r1 = std::gcd(p, q); | |
48 | // Check non-negative, so conversion to unsigned long doesn't alter value. | |
49 | VERIFY( r1 >= 0 ); | |
50 | // Check for expected result | |
51 | VERIFY( (unsigned long long)r1 == r ); | |
52 | // Check reversing arguments doesn't change result | |
53 | VERIFY( std::gcd(q, p) == r1 ); | |
54 | ||
55 | P pabs = p < 0 ? -p : p; | |
56 | VERIFY( std::gcd(p, p) == pabs ); | |
57 | VERIFY( std::gcd(0, p) == pabs ); | |
58 | VERIFY( std::gcd(p, 0) == pabs ); | |
59 | VERIFY( std::gcd(1, p) == 1 ); | |
60 | VERIFY( std::gcd(p, 1) == 1 ); | |
61 | Q qabs = q < 0 ? -q : q; | |
62 | VERIFY( std::gcd(q, q) == qabs ); | |
63 | VERIFY( std::gcd(0, q) == qabs ); | |
64 | VERIFY( std::gcd(q, 0) == qabs ); | |
65 | VERIFY( std::gcd(1, q) == 1 ); | |
66 | VERIFY( std::gcd(q, 1) == 1 ); | |
67 | VERIFY( std::gcd(r, r) == r ); | |
68 | VERIFY( std::gcd(0, r) == r ); | |
69 | VERIFY( std::gcd(r, 0) == r ); | |
70 | VERIFY( std::gcd(1, r) == 1 ); | |
71 | VERIFY( std::gcd(r, 1) == 1 ); | |
72 | ||
73 | return true; | |
74 | } | |
75 | ||
76 | constexpr bool | |
77 | test01() | |
78 | { | |
79 | for (auto t : testcases) | |
80 | { | |
81 | check(t.p, t.q, t.r); | |
82 | ||
83 | if (t.p <= LONG_MAX && t.q <= LONG_MAX) | |
84 | { | |
85 | check( (long)t.p, (long)t.p, t.p); | |
86 | check(-(long)t.p, (long)t.p, t.p); | |
87 | check(-(long)t.p, -(long)t.p, t.p); | |
88 | ||
89 | check( (long)t.p, t.q, t.r); | |
90 | check(-(long)t.p, t.q, t.r); | |
91 | ||
92 | check(t.p, (long)t.q, t.r); | |
93 | check(t.p, -(long)t.q, t.r); | |
94 | ||
95 | check( (long)t.p, (long)t.q, t.r); | |
96 | check( (long)t.p, -(long)t.q, t.r); | |
97 | check(-(long)t.p, (long)t.q, t.r); | |
98 | check(-(long)t.p, -(long)t.q, t.r); | |
99 | } | |
100 | ||
101 | if (t.p <= INT_MAX && t.q <= INT_MAX) | |
102 | { | |
103 | check((long)t.p, (int)t.q, t.r); | |
104 | check(-(int)t.p, (long)t.q, t.r); | |
105 | ||
106 | check( (int)t.p, (unsigned)t.q, t.r); | |
107 | check(-(int)t.p, (unsigned)t.q, t.r); | |
108 | ||
109 | check(-(int)t.p, -(int)t.q, t.r); | |
110 | check(-(int)t.p, -(long)t.q, t.r); | |
111 | } | |
112 | ||
113 | if (t.p <= SHRT_MAX && t.q <= SHRT_MAX) | |
114 | { | |
115 | check( (long)t.p, (short)t.q, t.r); | |
116 | check(-(short)t.p, (long)t.q, t.r); | |
117 | ||
118 | check( (short)t.p, (unsigned short)t.q, t.r); | |
119 | check(-(short)t.p, (unsigned short)t.q, t.r); | |
120 | ||
121 | check(-(short)t.p, -(short)t.q, t.r); | |
122 | check(-(short)t.p, -(long)t.q, t.r); | |
123 | } | |
124 | } | |
125 | return true; | |
126 | } | |
127 | ||
128 | ||
129 | int main() | |
130 | { | |
131 | static_assert( test01() ); // constexpr | |
132 | VERIFY( test01() ); // non-constexpr | |
133 | } |