libstdc++
|
00001 // <numeric> -*- C++ -*- 00002 00003 // Copyright (C) 2001-2017 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 namespace __detail 00083 { 00084 _GLIBCXX_BEGIN_NAMESPACE_VERSION 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 00121 _GLIBCXX_END_NAMESPACE_VERSION 00122 } 00123 00124 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00125 00126 #if __cplusplus > 201402L 00127 00128 #define __cpp_lib_gcd_lcm 201606 00129 // These were used in drafts of SD-6: 00130 #define __cpp_lib_gcd 201606 00131 #define __cpp_lib_lcm 201606 00132 00133 /// Greatest common divisor 00134 template<typename _Mn, typename _Nn> 00135 constexpr common_type_t<_Mn, _Nn> 00136 gcd(_Mn __m, _Nn __n) 00137 { 00138 static_assert(is_integral<_Mn>::value, "gcd arguments are integers"); 00139 static_assert(is_integral<_Nn>::value, "gcd arguments are integers"); 00140 static_assert(!is_same<_Mn, bool>::value, "gcd arguments are not bools"); 00141 static_assert(!is_same<_Nn, bool>::value, "gcd arguments are not bools"); 00142 return __detail::__gcd(__m, __n); 00143 } 00144 00145 /// Least common multiple 00146 template<typename _Mn, typename _Nn> 00147 constexpr common_type_t<_Mn, _Nn> 00148 lcm(_Mn __m, _Nn __n) 00149 { 00150 static_assert(is_integral<_Mn>::value, "lcm arguments are integers"); 00151 static_assert(is_integral<_Nn>::value, "lcm arguments are integers"); 00152 static_assert(!is_same<_Mn, bool>::value, "lcm arguments are not bools"); 00153 static_assert(!is_same<_Nn, bool>::value, "lcm arguments are not bools"); 00154 return __detail::__lcm(__m, __n); 00155 } 00156 00157 #endif // C++17 00158 00159 _GLIBCXX_END_NAMESPACE_VERSION 00160 } // namespace std 00161 00162 #endif // C++14 00163 00164 00165 #endif /* _GLIBCXX_NUMERIC */