1    	// <numeric> -*- C++ -*-
2    	
3    	// Copyright (C) 2001-2017 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   	namespace __detail
83   	{
84   	_GLIBCXX_BEGIN_NAMESPACE_VERSION
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  	
121  	_GLIBCXX_END_NAMESPACE_VERSION
122  	}
123  	
124  	_GLIBCXX_BEGIN_NAMESPACE_VERSION
125  	
126  	#if __cplusplus > 201402L
127  	
128  	#define __cpp_lib_gcd_lcm 201606
129  	// These were used in drafts of SD-6:
130  	#define __cpp_lib_gcd 201606
131  	#define __cpp_lib_lcm 201606
132  	
133  	  /// Greatest common divisor
134  	  template<typename _Mn, typename _Nn>
135  	    constexpr common_type_t<_Mn, _Nn>
136  	    gcd(_Mn __m, _Nn __n)
137  	    {
138  	      static_assert(is_integral<_Mn>::value, "gcd arguments are integers");
139  	      static_assert(is_integral<_Nn>::value, "gcd arguments are integers");
140  	      static_assert(!is_same<_Mn, bool>::value, "gcd arguments are not bools");
141  	      static_assert(!is_same<_Nn, bool>::value, "gcd arguments are not bools");
142  	      return __detail::__gcd(__m, __n);
143  	    }
144  	
145  	  /// Least common multiple
146  	  template<typename _Mn, typename _Nn>
147  	    constexpr common_type_t<_Mn, _Nn>
148  	    lcm(_Mn __m, _Nn __n)
149  	    {
150  	      static_assert(is_integral<_Mn>::value, "lcm arguments are integers");
151  	      static_assert(is_integral<_Nn>::value, "lcm arguments are integers");
152  	      static_assert(!is_same<_Mn, bool>::value, "lcm arguments are not bools");
153  	      static_assert(!is_same<_Nn, bool>::value, "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