libstdc++
|
00001 // <numeric> -*- C++ -*- 00002 00003 // Copyright (C) 2001-2019 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /* 00026 * 00027 * Copyright (c) 1994 00028 * Hewlett-Packard Company 00029 * 00030 * Permission to use, copy, modify, distribute and sell this software 00031 * and its documentation for any purpose is hereby granted without fee, 00032 * provided that the above copyright notice appear in all copies and 00033 * that both that copyright notice and this permission notice appear 00034 * in supporting documentation. Hewlett-Packard Company makes no 00035 * representations about the suitability of this software for any 00036 * purpose. It is provided "as is" without express or implied warranty. 00037 * 00038 * 00039 * Copyright (c) 1996,1997 00040 * Silicon Graphics Computer Systems, Inc. 00041 * 00042 * Permission to use, copy, modify, distribute and sell this software 00043 * and its documentation for any purpose is hereby granted without fee, 00044 * provided that the above copyright notice appear in all copies and 00045 * that both that copyright notice and this permission notice appear 00046 * in supporting documentation. Silicon Graphics makes no 00047 * representations about the suitability of this software for any 00048 * purpose. It is provided "as is" without express or implied warranty. 00049 */ 00050 00051 /** @file include/numeric 00052 * This is a Standard C++ Library header. 00053 */ 00054 00055 #ifndef _GLIBCXX_NUMERIC 00056 #define _GLIBCXX_NUMERIC 1 00057 00058 #pragma GCC system_header 00059 00060 #include <bits/c++config.h> 00061 #include <bits/stl_iterator_base_types.h> 00062 #include <bits/stl_numeric.h> 00063 00064 #ifdef _GLIBCXX_PARALLEL 00065 # include <parallel/numeric> 00066 #endif 00067 00068 /** 00069 * @defgroup numerics Numerics 00070 * 00071 * Components for performing numeric operations. Includes support for 00072 * for complex number types, random number generation, numeric 00073 * (n-at-a-time) arrays, generalized numeric algorithms, and special 00074 * math functions. 00075 */ 00076 00077 #if __cplusplus >= 201402L 00078 #include <type_traits> 00079 00080 namespace std _GLIBCXX_VISIBILITY(default) 00081 { 00082 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00083 00084 namespace __detail 00085 { 00086 // std::abs is not constexpr and doesn't support unsigned integers. 00087 template<typename _Tp> 00088 constexpr 00089 enable_if_t<__and_<is_integral<_Tp>, is_signed<_Tp>>::value, _Tp> 00090 __abs_integral(_Tp __val) 00091 { return __val < 0 ? -__val : __val; } 00092 00093 template<typename _Tp> 00094 constexpr 00095 enable_if_t<__and_<is_integral<_Tp>, is_unsigned<_Tp>>::value, _Tp> 00096 __abs_integral(_Tp __val) 00097 { return __val; } 00098 00099 void __abs_integral(bool) = delete; 00100 00101 template<typename _Mn, typename _Nn> 00102 constexpr common_type_t<_Mn, _Nn> 00103 __gcd(_Mn __m, _Nn __n) 00104 { 00105 return __m == 0 ? __detail::__abs_integral(__n) 00106 : __n == 0 ? __detail::__abs_integral(__m) 00107 : __detail::__gcd(__n, __m % __n); 00108 } 00109 00110 /// Least common multiple 00111 template<typename _Mn, typename _Nn> 00112 constexpr common_type_t<_Mn, _Nn> 00113 __lcm(_Mn __m, _Nn __n) 00114 { 00115 return (__m != 0 && __n != 0) 00116 ? (__detail::__abs_integral(__m) / __detail::__gcd(__m, __n)) 00117 * __detail::__abs_integral(__n) 00118 : 0; 00119 } 00120 } // namespace __detail 00121 00122 #if __cplusplus >= 201703L 00123 00124 #define __cpp_lib_gcd_lcm 201606 00125 // These were used in drafts of SD-6: 00126 #define __cpp_lib_gcd 201606 00127 #define __cpp_lib_lcm 201606 00128 00129 /// Greatest common divisor 00130 template<typename _Mn, typename _Nn> 00131 constexpr common_type_t<_Mn, _Nn> 00132 gcd(_Mn __m, _Nn __n) 00133 { 00134 static_assert(is_integral_v<_Mn>, "gcd arguments are integers"); 00135 static_assert(is_integral_v<_Nn>, "gcd arguments are integers"); 00136 static_assert(!is_same_v<remove_cv_t<_Mn>, bool>, 00137 "gcd arguments are not bools"); 00138 static_assert(!is_same_v<remove_cv_t<_Nn>, bool>, 00139 "gcd arguments are not bools"); 00140 return __detail::__gcd(__m, __n); 00141 } 00142 00143 /// Least common multiple 00144 template<typename _Mn, typename _Nn> 00145 constexpr common_type_t<_Mn, _Nn> 00146 lcm(_Mn __m, _Nn __n) 00147 { 00148 static_assert(is_integral_v<_Mn>, "lcm arguments are integers"); 00149 static_assert(is_integral_v<_Nn>, "lcm arguments are integers"); 00150 static_assert(!is_same_v<remove_cv_t<_Mn>, bool>, 00151 "lcm arguments are not bools"); 00152 static_assert(!is_same_v<remove_cv_t<_Nn>, bool>, 00153 "lcm arguments are not bools"); 00154 return __detail::__lcm(__m, __n); 00155 } 00156 00157 #endif // C++17 00158 00159 #if __cplusplus > 201703L 00160 // midpoint 00161 # define __cpp_lib_interpolate 201902L 00162 00163 template<typename _Tp> 00164 constexpr 00165 enable_if_t<__and_v<is_arithmetic<_Tp>, is_same<remove_cv_t<_Tp>, _Tp>, 00166 __not_<is_same<_Tp, bool>>>, 00167 _Tp> 00168 midpoint(_Tp __a, _Tp __b) noexcept 00169 { 00170 if constexpr (is_integral_v<_Tp>) 00171 { 00172 using _Up = make_unsigned_t<_Tp>; 00173 00174 int __k = 1; 00175 _Up __m = __a; 00176 _Up __M = __b; 00177 if (__a > __b) 00178 { 00179 __k = -1; 00180 __m = __b; 00181 __M = __a; 00182 } 00183 return __a + __k * _Tp(_Up(__M - __m) / 2); 00184 } 00185 else 00186 { 00187 return __builtin_isnormal(__a) && __builtin_isnormal(__b) 00188 ? __a / 2 + __b / 2 00189 : (__a + __b) / 2; 00190 } 00191 } 00192 00193 template<typename _Tp> 00194 constexpr 00195 enable_if_t<__and_v<is_object<_Tp>, bool_constant<sizeof(_Tp) != 0>>, _Tp*> 00196 midpoint(_Tp* __a, _Tp* __b) noexcept 00197 { 00198 return __a + (__b - __a) / 2; 00199 } 00200 #endif // C++20 00201 00202 _GLIBCXX_END_NAMESPACE_VERSION 00203 } // namespace std 00204 00205 #endif // C++14 00206 00207 #if __cplusplus > 201402L 00208 // Parallel STL algorithms 00209 # if __PSTL_EXECUTION_POLICIES_DEFINED 00210 // If <execution> has already been included, pull in implementations 00211 # include <pstl/glue_numeric_impl.h> 00212 # else 00213 // Otherwise just pull in forward declarations 00214 # include <pstl/glue_numeric_defs.h> 00215 # define __PSTL_NUMERIC_FORWARD_DECLARED 1 00216 # endif 00217 00218 // Feature test macro for parallel algorithms 00219 # define __cpp_lib_parallel_algorithm 201703L 00220 #endif // C++17 00221 00222 #endif /* _GLIBCXX_NUMERIC */