1*38fd1498Szrj// Numeric extensions -*- C++ -*- 2*38fd1498Szrj 3*38fd1498Szrj// Copyright (C) 2002-2018 Free Software Foundation, Inc. 4*38fd1498Szrj// 5*38fd1498Szrj// This file is part of the GNU ISO C++ Library. This library is free 6*38fd1498Szrj// software; you can redistribute it and/or modify it under the 7*38fd1498Szrj// terms of the GNU General Public License as published by the 8*38fd1498Szrj// Free Software Foundation; either version 3, or (at your option) 9*38fd1498Szrj// any later version. 10*38fd1498Szrj 11*38fd1498Szrj// This library is distributed in the hope that it will be useful, 12*38fd1498Szrj// but WITHOUT ANY WARRANTY; without even the implied warranty of 13*38fd1498Szrj// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*38fd1498Szrj// GNU General Public License for more details. 15*38fd1498Szrj 16*38fd1498Szrj// Under Section 7 of GPL version 3, you are granted additional 17*38fd1498Szrj// permissions described in the GCC Runtime Library Exception, version 18*38fd1498Szrj// 3.1, as published by the Free Software Foundation. 19*38fd1498Szrj 20*38fd1498Szrj// You should have received a copy of the GNU General Public License and 21*38fd1498Szrj// a copy of the GCC Runtime Library Exception along with this program; 22*38fd1498Szrj// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*38fd1498Szrj// <http://www.gnu.org/licenses/>. 24*38fd1498Szrj 25*38fd1498Szrj/* 26*38fd1498Szrj * 27*38fd1498Szrj * Copyright (c) 1994 28*38fd1498Szrj * Hewlett-Packard Company 29*38fd1498Szrj * 30*38fd1498Szrj * Permission to use, copy, modify, distribute and sell this software 31*38fd1498Szrj * and its documentation for any purpose is hereby granted without fee, 32*38fd1498Szrj * provided that the above copyright notice appear in all copies and 33*38fd1498Szrj * that both that copyright notice and this permission notice appear 34*38fd1498Szrj * in supporting documentation. Hewlett-Packard Company makes no 35*38fd1498Szrj * representations about the suitability of this software for any 36*38fd1498Szrj * purpose. It is provided "as is" without express or implied warranty. 37*38fd1498Szrj * 38*38fd1498Szrj * 39*38fd1498Szrj * Copyright (c) 1996 40*38fd1498Szrj * Silicon Graphics Computer Systems, Inc. 41*38fd1498Szrj * 42*38fd1498Szrj * Permission to use, copy, modify, distribute and sell this software 43*38fd1498Szrj * and its documentation for any purpose is hereby granted without fee, 44*38fd1498Szrj * provided that the above copyright notice appear in all copies and 45*38fd1498Szrj * that both that copyright notice and this permission notice appear 46*38fd1498Szrj * in supporting documentation. Silicon Graphics makes no 47*38fd1498Szrj * representations about the suitability of this software for any 48*38fd1498Szrj * purpose. It is provided "as is" without express or implied warranty. 49*38fd1498Szrj */ 50*38fd1498Szrj 51*38fd1498Szrj/** @file ext/numeric 52*38fd1498Szrj * This file is a GNU extension to the Standard C++ Library (possibly 53*38fd1498Szrj * containing extensions from the HP/SGI STL subset). 54*38fd1498Szrj */ 55*38fd1498Szrj 56*38fd1498Szrj#ifndef _EXT_NUMERIC 57*38fd1498Szrj#define _EXT_NUMERIC 1 58*38fd1498Szrj 59*38fd1498Szrj#pragma GCC system_header 60*38fd1498Szrj 61*38fd1498Szrj#include <bits/concept_check.h> 62*38fd1498Szrj#include <numeric> 63*38fd1498Szrj 64*38fd1498Szrj#include <ext/functional> // For identity_element 65*38fd1498Szrj 66*38fd1498Szrjnamespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 67*38fd1498Szrj{ 68*38fd1498Szrj_GLIBCXX_BEGIN_NAMESPACE_VERSION 69*38fd1498Szrj 70*38fd1498Szrj // Returns __x ** __n, where __n >= 0. _Note that "multiplication" 71*38fd1498Szrj // is required to be associative, but not necessarily commutative. 72*38fd1498Szrj template<typename _Tp, typename _Integer, typename _MonoidOperation> 73*38fd1498Szrj _Tp 74*38fd1498Szrj __power(_Tp __x, _Integer __n, _MonoidOperation __monoid_op) 75*38fd1498Szrj { 76*38fd1498Szrj if (__n == 0) 77*38fd1498Szrj return identity_element(__monoid_op); 78*38fd1498Szrj else 79*38fd1498Szrj { 80*38fd1498Szrj while ((__n & 1) == 0) 81*38fd1498Szrj { 82*38fd1498Szrj __n >>= 1; 83*38fd1498Szrj __x = __monoid_op(__x, __x); 84*38fd1498Szrj } 85*38fd1498Szrj 86*38fd1498Szrj _Tp __result = __x; 87*38fd1498Szrj __n >>= 1; 88*38fd1498Szrj while (__n != 0) 89*38fd1498Szrj { 90*38fd1498Szrj __x = __monoid_op(__x, __x); 91*38fd1498Szrj if ((__n & 1) != 0) 92*38fd1498Szrj __result = __monoid_op(__result, __x); 93*38fd1498Szrj __n >>= 1; 94*38fd1498Szrj } 95*38fd1498Szrj return __result; 96*38fd1498Szrj } 97*38fd1498Szrj } 98*38fd1498Szrj 99*38fd1498Szrj template<typename _Tp, typename _Integer> 100*38fd1498Szrj inline _Tp 101*38fd1498Szrj __power(_Tp __x, _Integer __n) 102*38fd1498Szrj { return __power(__x, __n, std::multiplies<_Tp>()); } 103*38fd1498Szrj 104*38fd1498Szrj /** 105*38fd1498Szrj * This is an SGI extension. 106*38fd1498Szrj * @ingroup SGIextensions 107*38fd1498Szrj * @doctodo 108*38fd1498Szrj */ 109*38fd1498Szrj // Alias for the internal name __power. Note that power is an extension, 110*38fd1498Szrj // not part of the C++ standard. 111*38fd1498Szrj template<typename _Tp, typename _Integer, typename _MonoidOperation> 112*38fd1498Szrj inline _Tp 113*38fd1498Szrj power(_Tp __x, _Integer __n, _MonoidOperation __monoid_op) 114*38fd1498Szrj { return __power(__x, __n, __monoid_op); } 115*38fd1498Szrj 116*38fd1498Szrj /** 117*38fd1498Szrj * This is an SGI extension. 118*38fd1498Szrj * @ingroup SGIextensions 119*38fd1498Szrj * @doctodo 120*38fd1498Szrj */ 121*38fd1498Szrj template<typename _Tp, typename _Integer> 122*38fd1498Szrj inline _Tp 123*38fd1498Szrj power(_Tp __x, _Integer __n) 124*38fd1498Szrj { return __power(__x, __n); } 125*38fd1498Szrj 126*38fd1498Szrj#if __cplusplus >= 201103L 127*38fd1498Szrj using std::iota; 128*38fd1498Szrj#else 129*38fd1498Szrj /** 130*38fd1498Szrj * This is an SGI extension. 131*38fd1498Szrj * @ingroup SGIextensions 132*38fd1498Szrj * @doctodo 133*38fd1498Szrj */ 134*38fd1498Szrj // iota is not part of the C++ standard. It is an extension. 135*38fd1498Szrj template<typename _ForwardIter, typename _Tp> 136*38fd1498Szrj void 137*38fd1498Szrj iota(_ForwardIter __first, _ForwardIter __last, _Tp __value) 138*38fd1498Szrj { 139*38fd1498Szrj // concept requirements 140*38fd1498Szrj __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>) 141*38fd1498Szrj __glibcxx_function_requires(_ConvertibleConcept<_Tp, 142*38fd1498Szrj typename std::iterator_traits<_ForwardIter>::value_type>) 143*38fd1498Szrj 144*38fd1498Szrj while (__first != __last) 145*38fd1498Szrj *__first++ = __value++; 146*38fd1498Szrj } 147*38fd1498Szrj#endif // C++11 148*38fd1498Szrj 149*38fd1498Szrj_GLIBCXX_END_NAMESPACE_VERSION 150*38fd1498Szrj} // namespace 151*38fd1498Szrj 152*38fd1498Szrj#endif 153