1 | // <numeric> -*- C++ -*- |
---|---|

2 | |

3 | // Copyright (C) 2001-2018 Free Software Foundation, Inc. |

4 | // |

5 | // This file is part of the GNU ISO C++ Library. This library is free |

6 | // software; you can redistribute it and/or modify it under the |

7 | // terms of the GNU General Public License as published by the |

8 | // Free Software Foundation; either version 3, or (at your option) |

9 | // any later version. |

10 | |

11 | // This library is distributed in the hope that it will be useful, |

12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |

13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |

14 | // GNU General Public License for more details. |

15 | |

16 | // Under Section 7 of GPL version 3, you are granted additional |

17 | // permissions described in the GCC Runtime Library Exception, version |

18 | // 3.1, as published by the Free Software Foundation. |

19 | |

20 | // You should have received a copy of the GNU General Public License and |

21 | // a copy of the GCC Runtime Library Exception along with this program; |

22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see |

23 | // <http://www.gnu.org/licenses/>. |

24 | |

25 | /* |

26 | * |

27 | * Copyright (c) 1994 |

28 | * Hewlett-Packard Company |

29 | * |

30 | * Permission to use, copy, modify, distribute and sell this software |

31 | * and its documentation for any purpose is hereby granted without fee, |

32 | * provided that the above copyright notice appear in all copies and |

33 | * that both that copyright notice and this permission notice appear |

34 | * in supporting documentation. Hewlett-Packard Company makes no |

35 | * representations about the suitability of this software for any |

36 | * purpose. It is provided "as is" without express or implied warranty. |

37 | * |

38 | * |

39 | * Copyright (c) 1996,1997 |

40 | * Silicon Graphics Computer Systems, Inc. |

41 | * |

42 | * Permission to use, copy, modify, distribute and sell this software |

43 | * and its documentation for any purpose is hereby granted without fee, |

44 | * provided that the above copyright notice appear in all copies and |

45 | * that both that copyright notice and this permission notice appear |

46 | * in supporting documentation. Silicon Graphics makes no |

47 | * representations about the suitability of this software for any |

48 | * purpose. It is provided "as is" without express or implied warranty. |

49 | */ |

50 | |

51 | /** @file include/numeric |

52 | * This is a Standard C++ Library header. |

53 | */ |

54 | |

55 | #ifndef _GLIBCXX_NUMERIC |

56 | #define _GLIBCXX_NUMERIC 1 |

57 | |

58 | #pragma GCC system_header |

59 | |

60 | #include <bits/c++config.h> |

61 | #include <bits/stl_iterator_base_types.h> |

62 | #include <bits/stl_numeric.h> |

63 | |

64 | #ifdef _GLIBCXX_PARALLEL |

65 | # include <parallel/numeric> |

66 | #endif |

67 | |

68 | /** |

69 | * @defgroup numerics Numerics |

70 | * |

71 | * Components for performing numeric operations. Includes support for |

72 | * for complex number types, random number generation, numeric |

73 | * (n-at-a-time) arrays, generalized numeric algorithms, and special |

74 | * math functions. |

75 | */ |

76 | |

77 | #if __cplusplus >= 201402L |

78 | #include <type_traits> |

79 | |

80 | namespace std _GLIBCXX_VISIBILITY(default) |

81 | { |

82 | _GLIBCXX_BEGIN_NAMESPACE_VERSION |

83 | |

84 | namespace __detail |

85 | { |

86 | // std::abs is not constexpr and doesn't support unsigned integers. |

87 | template<typename _Tp> |

88 | constexpr |

89 | enable_if_t<__and_<is_integral<_Tp>, is_signed<_Tp>>::value, _Tp> |

90 | __abs_integral(_Tp __val) |

91 | { return __val < 0 ? -__val : __val; } |

92 | |

93 | template<typename _Tp> |

94 | constexpr |

95 | enable_if_t<__and_<is_integral<_Tp>, is_unsigned<_Tp>>::value, _Tp> |

96 | __abs_integral(_Tp __val) |

97 | { return __val; } |

98 | |

99 | void __abs_integral(bool) = delete; |

100 | |

101 | template<typename _Mn, typename _Nn> |

102 | constexpr common_type_t<_Mn, _Nn> |

103 | __gcd(_Mn __m, _Nn __n) |

104 | { |

105 | return __m == 0 ? __detail::__abs_integral(__n) |

106 | : __n == 0 ? __detail::__abs_integral(__m) |

107 | : __detail::__gcd(__n, __m % __n); |

108 | } |

109 | |

110 | /// Least common multiple |

111 | template<typename _Mn, typename _Nn> |

112 | constexpr common_type_t<_Mn, _Nn> |

113 | __lcm(_Mn __m, _Nn __n) |

114 | { |

115 | return (__m != 0 && __n != 0) |

116 | ? (__detail::__abs_integral(__m) / __detail::__gcd(__m, __n)) |

117 | * __detail::__abs_integral(__n) |

118 | : 0; |

119 | } |

120 | } // namespace __detail |

121 | |

122 | #if __cplusplus > 201402L |

123 | |

124 | #define __cpp_lib_gcd_lcm 201606 |

125 | // These were used in drafts of SD-6: |

126 | #define __cpp_lib_gcd 201606 |

127 | #define __cpp_lib_lcm 201606 |

128 | |

129 | /// Greatest common divisor |

130 | template<typename _Mn, typename _Nn> |

131 | constexpr common_type_t<_Mn, _Nn> |

132 | gcd(_Mn __m, _Nn __n) |

133 | { |

134 | static_assert(is_integral_v<_Mn>, "gcd arguments are integers"); |

135 | static_assert(is_integral_v<_Nn>, "gcd arguments are integers"); |

136 | static_assert(!is_same_v<remove_cv_t<_Mn>, bool>, |

137 | "gcd arguments are not bools"); |

138 | static_assert(!is_same_v<remove_cv_t<_Nn>, bool>, |

139 | "gcd arguments are not bools"); |

140 | return __detail::__gcd(__m, __n); |

141 | } |

142 | |

143 | /// Least common multiple |

144 | template<typename _Mn, typename _Nn> |

145 | constexpr common_type_t<_Mn, _Nn> |

146 | lcm(_Mn __m, _Nn __n) |

147 | { |

148 | static_assert(is_integral_v<_Mn>, "lcm arguments are integers"); |

149 | static_assert(is_integral_v<_Nn>, "lcm arguments are integers"); |

150 | static_assert(!is_same_v<remove_cv_t<_Mn>, bool>, |

151 | "lcm arguments are not bools"); |

152 | static_assert(!is_same_v<remove_cv_t<_Nn>, bool>, |

153 | "lcm arguments are not bools"); |

154 | return __detail::__lcm(__m, __n); |

155 | } |

156 | |

157 | #endif // C++17 |

158 | |

159 | _GLIBCXX_END_NAMESPACE_VERSION |

160 | } // namespace std |

161 | |

162 | #endif // C++14 |

163 | |

164 | |

165 | #endif /* _GLIBCXX_NUMERIC */ |

166 |