xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/ext/numeric (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
136ac495dSmrg// Numeric extensions -*- C++ -*-
236ac495dSmrg
3*8feb0f0bSmrg// Copyright (C) 2002-2020 Free Software Foundation, Inc.
436ac495dSmrg//
536ac495dSmrg// This file is part of the GNU ISO C++ Library.  This library is free
636ac495dSmrg// software; you can redistribute it and/or modify it under the
736ac495dSmrg// terms of the GNU General Public License as published by the
836ac495dSmrg// Free Software Foundation; either version 3, or (at your option)
936ac495dSmrg// any later version.
1036ac495dSmrg
1136ac495dSmrg// This library is distributed in the hope that it will be useful,
1236ac495dSmrg// but WITHOUT ANY WARRANTY; without even the implied warranty of
1336ac495dSmrg// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1436ac495dSmrg// GNU General Public License for more details.
1536ac495dSmrg
1636ac495dSmrg// Under Section 7 of GPL version 3, you are granted additional
1736ac495dSmrg// permissions described in the GCC Runtime Library Exception, version
1836ac495dSmrg// 3.1, as published by the Free Software Foundation.
1936ac495dSmrg
2036ac495dSmrg// You should have received a copy of the GNU General Public License and
2136ac495dSmrg// a copy of the GCC Runtime Library Exception along with this program;
2236ac495dSmrg// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2336ac495dSmrg// <http://www.gnu.org/licenses/>.
2436ac495dSmrg
2536ac495dSmrg/*
2636ac495dSmrg *
2736ac495dSmrg * Copyright (c) 1994
2836ac495dSmrg * Hewlett-Packard Company
2936ac495dSmrg *
3036ac495dSmrg * Permission to use, copy, modify, distribute and sell this software
3136ac495dSmrg * and its documentation for any purpose is hereby granted without fee,
3236ac495dSmrg * provided that the above copyright notice appear in all copies and
3336ac495dSmrg * that both that copyright notice and this permission notice appear
3436ac495dSmrg * in supporting documentation.  Hewlett-Packard Company makes no
3536ac495dSmrg * representations about the suitability of this software for any
3636ac495dSmrg * purpose.  It is provided "as is" without express or implied warranty.
3736ac495dSmrg *
3836ac495dSmrg *
3936ac495dSmrg * Copyright (c) 1996
4036ac495dSmrg * Silicon Graphics Computer Systems, Inc.
4136ac495dSmrg *
4236ac495dSmrg * Permission to use, copy, modify, distribute and sell this software
4336ac495dSmrg * and its documentation for any purpose is hereby granted without fee,
4436ac495dSmrg * provided that the above copyright notice appear in all copies and
4536ac495dSmrg * that both that copyright notice and this permission notice appear
4636ac495dSmrg * in supporting documentation.  Silicon Graphics makes no
4736ac495dSmrg * representations about the suitability of this software for any
4836ac495dSmrg * purpose.  It is provided "as is" without express or implied warranty.
4936ac495dSmrg */
5036ac495dSmrg
5136ac495dSmrg/** @file ext/numeric
5236ac495dSmrg *  This file is a GNU extension to the Standard C++ Library (possibly
5336ac495dSmrg *  containing extensions from the HP/SGI STL subset).
5436ac495dSmrg */
5536ac495dSmrg
5636ac495dSmrg#ifndef _EXT_NUMERIC
5736ac495dSmrg#define _EXT_NUMERIC 1
5836ac495dSmrg
5936ac495dSmrg#pragma GCC system_header
6036ac495dSmrg
6136ac495dSmrg#include <bits/concept_check.h>
6236ac495dSmrg#include <numeric>
6336ac495dSmrg
6436ac495dSmrg#include <ext/functional> // For identity_element
6536ac495dSmrg
6636ac495dSmrgnamespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
6736ac495dSmrg{
6836ac495dSmrg_GLIBCXX_BEGIN_NAMESPACE_VERSION
6936ac495dSmrg
7036ac495dSmrg  // Returns __x ** __n, where __n >= 0.  _Note that "multiplication"
7136ac495dSmrg  // is required to be associative, but not necessarily commutative.
7236ac495dSmrg  template<typename _Tp, typename _Integer, typename _MonoidOperation>
7336ac495dSmrg    _Tp
7436ac495dSmrg    __power(_Tp __x, _Integer __n, _MonoidOperation __monoid_op)
7536ac495dSmrg    {
7636ac495dSmrg      if (__n == 0)
7736ac495dSmrg	return identity_element(__monoid_op);
7836ac495dSmrg      else
7936ac495dSmrg	{
8036ac495dSmrg	  while ((__n & 1) == 0)
8136ac495dSmrg	    {
8236ac495dSmrg	      __n >>= 1;
8336ac495dSmrg	      __x = __monoid_op(__x, __x);
8436ac495dSmrg	    }
8536ac495dSmrg
8636ac495dSmrg	  _Tp __result = __x;
8736ac495dSmrg	  __n >>= 1;
8836ac495dSmrg	  while (__n != 0)
8936ac495dSmrg	    {
9036ac495dSmrg	      __x = __monoid_op(__x, __x);
9136ac495dSmrg	      if ((__n & 1) != 0)
9236ac495dSmrg		__result = __monoid_op(__result, __x);
9336ac495dSmrg	      __n >>= 1;
9436ac495dSmrg	    }
9536ac495dSmrg	  return __result;
9636ac495dSmrg	}
9736ac495dSmrg    }
9836ac495dSmrg
9936ac495dSmrg  template<typename _Tp, typename _Integer>
10036ac495dSmrg    inline _Tp
10136ac495dSmrg    __power(_Tp __x, _Integer __n)
10236ac495dSmrg    { return __power(__x, __n, std::multiplies<_Tp>()); }
10336ac495dSmrg
10436ac495dSmrg  /**
10536ac495dSmrg   *  This is an SGI extension.
10636ac495dSmrg   *  @ingroup SGIextensions
10736ac495dSmrg   *  @doctodo
10836ac495dSmrg  */
10936ac495dSmrg  // Alias for the internal name __power.  Note that power is an extension,
11036ac495dSmrg  // not part of the C++ standard.
11136ac495dSmrg  template<typename _Tp, typename _Integer, typename _MonoidOperation>
11236ac495dSmrg    inline _Tp
11336ac495dSmrg    power(_Tp __x, _Integer __n, _MonoidOperation __monoid_op)
11436ac495dSmrg    { return __power(__x, __n, __monoid_op); }
11536ac495dSmrg
11636ac495dSmrg  /**
11736ac495dSmrg   *  This is an SGI extension.
11836ac495dSmrg   *  @ingroup SGIextensions
11936ac495dSmrg   *  @doctodo
12036ac495dSmrg  */
12136ac495dSmrg  template<typename _Tp, typename _Integer>
12236ac495dSmrg    inline _Tp
12336ac495dSmrg    power(_Tp __x, _Integer __n)
12436ac495dSmrg    { return __power(__x, __n); }
12536ac495dSmrg
12636ac495dSmrg#if __cplusplus >= 201103L
12736ac495dSmrg  using std::iota;
12836ac495dSmrg#else
12936ac495dSmrg  /**
13036ac495dSmrg   *  This is an SGI extension.
13136ac495dSmrg   *  @ingroup SGIextensions
13236ac495dSmrg   *  @doctodo
13336ac495dSmrg  */
134*8feb0f0bSmrg  // iota is not part of the standard until C++11.  It is an extension.
13536ac495dSmrg  template<typename _ForwardIter, typename _Tp>
13636ac495dSmrg    void
13736ac495dSmrg    iota(_ForwardIter __first, _ForwardIter __last, _Tp __value)
13836ac495dSmrg    {
13936ac495dSmrg      // concept requirements
14036ac495dSmrg      __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>)
14136ac495dSmrg      __glibcxx_function_requires(_ConvertibleConcept<_Tp,
14236ac495dSmrg	    typename std::iterator_traits<_ForwardIter>::value_type>)
14336ac495dSmrg
14436ac495dSmrg      while (__first != __last)
14536ac495dSmrg	*__first++ = __value++;
14636ac495dSmrg    }
14736ac495dSmrg#endif  // C++11
14836ac495dSmrg
14936ac495dSmrg_GLIBCXX_END_NAMESPACE_VERSION
15036ac495dSmrg} // namespace
15136ac495dSmrg
15236ac495dSmrg#endif
153