Home | History | Annotate | Download | only in bits
      1 // Numeric functions implementation -*- C++ -*-
      2 
      3 // Copyright (C) 2001-2013 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 bits/stl_numeric.h
     52  *  This is an internal header file, included by other library headers.
     53  *  Do not attempt to use it directly. @headername{numeric}
     54  */
     55 
     56 #ifndef _STL_NUMERIC_H
     57 #define _STL_NUMERIC_H 1
     58 
     59 #include <bits/concept_check.h>
     60 #include <debug/debug.h>
     61 #include <bits/move.h> // For _GLIBCXX_MOVE
     62 
     63 #if __cplusplus >= 201103L
     64 
     65 namespace std _GLIBCXX_VISIBILITY(default)
     66 {
     67 _GLIBCXX_BEGIN_NAMESPACE_VERSION
     68 
     69   /**
     70    *  @brief  Create a range of sequentially increasing values.
     71    *
     72    *  For each element in the range @p [first,last) assigns @p value and
     73    *  increments @p value as if by @p ++value.
     74    *
     75    *  @param  __first  Start of range.
     76    *  @param  __last  End of range.
     77    *  @param  __value  Starting value.
     78    *  @return  Nothing.
     79    */
     80   template<typename _ForwardIterator, typename _Tp>
     81     void
     82     iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value)
     83     {
     84       // concept requirements
     85       __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
     86 				  _ForwardIterator>)
     87       __glibcxx_function_requires(_ConvertibleConcept<_Tp,
     88 	    typename iterator_traits<_ForwardIterator>::value_type>)
     89       __glibcxx_requires_valid_range(__first, __last);
     90 
     91       for (; __first != __last; ++__first)
     92 	{
     93 	  *__first = __value;
     94 	  ++__value;
     95 	}
     96     }
     97 
     98 _GLIBCXX_END_NAMESPACE_VERSION
     99 } // namespace std
    100 
    101 #endif
    102 
    103 namespace std _GLIBCXX_VISIBILITY(default)
    104 {
    105 _GLIBCXX_BEGIN_NAMESPACE_ALGO
    106 
    107   /**
    108    *  @brief  Accumulate values in a range.
    109    *
    110    *  Accumulates the values in the range [first,last) using operator+().  The
    111    *  initial value is @a init.  The values are processed in order.
    112    *
    113    *  @param  __first  Start of range.
    114    *  @param  __last  End of range.
    115    *  @param  __init  Starting value to add other values to.
    116    *  @return  The final sum.
    117    */
    118   template<typename _InputIterator, typename _Tp>
    119     inline _Tp
    120     accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
    121     {
    122       // concept requirements
    123       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
    124       __glibcxx_requires_valid_range(__first, __last);
    125 
    126       for (; __first != __last; ++__first)
    127 	__init = __init + *__first;
    128       return __init;
    129     }
    130 
    131   /**
    132    *  @brief  Accumulate values in a range with operation.
    133    *
    134    *  Accumulates the values in the range [first,last) using the function
    135    *  object @p __binary_op.  The initial value is @p __init.  The values are
    136    *  processed in order.
    137    *
    138    *  @param  __first  Start of range.
    139    *  @param  __last  End of range.
    140    *  @param  __init  Starting value to add other values to.
    141    *  @param  __binary_op  Function object to accumulate with.
    142    *  @return  The final sum.
    143    */
    144   template<typename _InputIterator, typename _Tp, typename _BinaryOperation>
    145     inline _Tp
    146     accumulate(_InputIterator __first, _InputIterator __last, _Tp __init,
    147 	       _BinaryOperation __binary_op)
    148     {
    149       // concept requirements
    150       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
    151       __glibcxx_requires_valid_range(__first, __last);
    152 
    153       for (; __first != __last; ++__first)
    154 	__init = __binary_op(__init, *__first);
    155       return __init;
    156     }
    157 
    158   /**
    159    *  @brief  Compute inner product of two ranges.
    160    *
    161    *  Starting with an initial value of @p __init, multiplies successive
    162    *  elements from the two ranges and adds each product into the accumulated
    163    *  value using operator+().  The values in the ranges are processed in
    164    *  order.
    165    *
    166    *  @param  __first1  Start of range 1.
    167    *  @param  __last1  End of range 1.
    168    *  @param  __first2  Start of range 2.
    169    *  @param  __init  Starting value to add other values to.
    170    *  @return  The final inner product.
    171    */
    172   template<typename _InputIterator1, typename _InputIterator2, typename _Tp>
    173     inline _Tp
    174     inner_product(_InputIterator1 __first1, _InputIterator1 __last1,
    175 		  _InputIterator2 __first2, _Tp __init)
    176     {
    177       // concept requirements
    178       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
    179       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
    180       __glibcxx_requires_valid_range(__first1, __last1);
    181 
    182       for (; __first1 != __last1; ++__first1, ++__first2)
    183 	__init = __init + (*__first1 * *__first2);
    184       return __init;
    185     }
    186 
    187   /**
    188    *  @brief  Compute inner product of two ranges.
    189    *
    190    *  Starting with an initial value of @p __init, applies @p __binary_op2 to
    191    *  successive elements from the two ranges and accumulates each result into
    192    *  the accumulated value using @p __binary_op1.  The values in the ranges are
    193    *  processed in order.
    194    *
    195    *  @param  __first1  Start of range 1.
    196    *  @param  __last1  End of range 1.
    197    *  @param  __first2  Start of range 2.
    198    *  @param  __init  Starting value to add other values to.
    199    *  @param  __binary_op1  Function object to accumulate with.
    200    *  @param  __binary_op2  Function object to apply to pairs of input values.
    201    *  @return  The final inner product.
    202    */
    203   template<typename _InputIterator1, typename _InputIterator2, typename _Tp,
    204 	   typename _BinaryOperation1, typename _BinaryOperation2>
    205     inline _Tp
    206     inner_product(_InputIterator1 __first1, _InputIterator1 __last1,
    207 		  _InputIterator2 __first2, _Tp __init,
    208 		  _BinaryOperation1 __binary_op1,
    209 		  _BinaryOperation2 __binary_op2)
    210     {
    211       // concept requirements
    212       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
    213       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
    214       __glibcxx_requires_valid_range(__first1, __last1);
    215 
    216       for (; __first1 != __last1; ++__first1, ++__first2)
    217 	__init = __binary_op1(__init, __binary_op2(*__first1, *__first2));
    218       return __init;
    219     }
    220 
    221   /**
    222    *  @brief  Return list of partial sums
    223    *
    224    *  Accumulates the values in the range [first,last) using the @c + operator.
    225    *  As each successive input value is added into the total, that partial sum
    226    *  is written to @p __result.  Therefore, the first value in @p __result is
    227    *  the first value of the input, the second value in @p __result is the sum
    228    *  of the first and second input values, and so on.
    229    *
    230    *  @param  __first  Start of input range.
    231    *  @param  __last  End of input range.
    232    *  @param  __result  Output sum.
    233    *  @return  Iterator pointing just beyond the values written to __result.
    234    */
    235   template<typename _InputIterator, typename _OutputIterator>
    236     _OutputIterator
    237     partial_sum(_InputIterator __first, _InputIterator __last,
    238 		_OutputIterator __result)
    239     {
    240       typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
    241 
    242       // concept requirements
    243       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
    244       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
    245 				                         _ValueType>)
    246       __glibcxx_requires_valid_range(__first, __last);
    247 
    248       if (__first == __last)
    249 	return __result;
    250       _ValueType __value = *__first;
    251       *__result = __value;
    252       while (++__first != __last)
    253 	{
    254 	  __value = __value + *__first;
    255 	  *++__result = __value;
    256 	}
    257       return ++__result;
    258     }
    259 
    260   /**
    261    *  @brief  Return list of partial sums
    262    *
    263    *  Accumulates the values in the range [first,last) using @p __binary_op.
    264    *  As each successive input value is added into the total, that partial sum
    265    *  is written to @p __result.  Therefore, the first value in @p __result is
    266    *  the first value of the input, the second value in @p __result is the sum
    267    *  of the first and second input values, and so on.
    268    *
    269    *  @param  __first  Start of input range.
    270    *  @param  __last  End of input range.
    271    *  @param  __result  Output sum.
    272    *  @param  __binary_op  Function object.
    273    *  @return  Iterator pointing just beyond the values written to __result.
    274    */
    275   template<typename _InputIterator, typename _OutputIterator,
    276 	   typename _BinaryOperation>
    277     _OutputIterator
    278     partial_sum(_InputIterator __first, _InputIterator __last,
    279 		_OutputIterator __result, _BinaryOperation __binary_op)
    280     {
    281       typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
    282 
    283       // concept requirements
    284       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
    285       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
    286 				                         _ValueType>)
    287       __glibcxx_requires_valid_range(__first, __last);
    288 
    289       if (__first == __last)
    290 	return __result;
    291       _ValueType __value = *__first;
    292       *__result = __value;
    293       while (++__first != __last)
    294 	{
    295 	  __value = __binary_op(__value, *__first);
    296 	  *++__result = __value;
    297 	}
    298       return ++__result;
    299     }
    300 
    301   /**
    302    *  @brief  Return differences between adjacent values.
    303    *
    304    *  Computes the difference between adjacent values in the range
    305    *  [first,last) using operator-() and writes the result to @p __result.
    306    *
    307    *  @param  __first  Start of input range.
    308    *  @param  __last  End of input range.
    309    *  @param  __result  Output sums.
    310    *  @return  Iterator pointing just beyond the values written to result.
    311    *
    312    *  _GLIBCXX_RESOLVE_LIB_DEFECTS
    313    *  DR 539. partial_sum and adjacent_difference should mention requirements
    314    */
    315   template<typename _InputIterator, typename _OutputIterator>
    316     _OutputIterator
    317     adjacent_difference(_InputIterator __first,
    318 			_InputIterator __last, _OutputIterator __result)
    319     {
    320       typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
    321 
    322       // concept requirements
    323       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
    324       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
    325 				                         _ValueType>)
    326       __glibcxx_requires_valid_range(__first, __last);
    327 
    328       if (__first == __last)
    329 	return __result;
    330       _ValueType __value = *__first;
    331       *__result = __value;
    332       while (++__first != __last)
    333 	{
    334 	  _ValueType __tmp = *__first;
    335 	  *++__result = __tmp - __value;
    336 	  __value = _GLIBCXX_MOVE(__tmp);
    337 	}
    338       return ++__result;
    339     }
    340 
    341   /**
    342    *  @brief  Return differences between adjacent values.
    343    *
    344    *  Computes the difference between adjacent values in the range
    345    *  [__first,__last) using the function object @p __binary_op and writes the
    346    *  result to @p __result.
    347    *
    348    *  @param  __first  Start of input range.
    349    *  @param  __last  End of input range.
    350    *  @param  __result  Output sum.
    351    *  @param  __binary_op Function object.
    352    *  @return  Iterator pointing just beyond the values written to result.
    353    *
    354    *  _GLIBCXX_RESOLVE_LIB_DEFECTS
    355    *  DR 539. partial_sum and adjacent_difference should mention requirements
    356    */
    357   template<typename _InputIterator, typename _OutputIterator,
    358 	   typename _BinaryOperation>
    359     _OutputIterator
    360     adjacent_difference(_InputIterator __first, _InputIterator __last,
    361 			_OutputIterator __result, _BinaryOperation __binary_op)
    362     {
    363       typedef typename iterator_traits<_InputIterator>::value_type _ValueType;
    364 
    365       // concept requirements
    366       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
    367       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
    368 				                         _ValueType>)
    369       __glibcxx_requires_valid_range(__first, __last);
    370 
    371       if (__first == __last)
    372 	return __result;
    373       _ValueType __value = *__first;
    374       *__result = __value;
    375       while (++__first != __last)
    376 	{
    377 	  _ValueType __tmp = *__first;
    378 	  *++__result = __binary_op(__tmp, __value);
    379 	  __value = _GLIBCXX_MOVE(__tmp);
    380 	}
    381       return ++__result;
    382     }
    383 
    384 _GLIBCXX_END_NAMESPACE_ALGO
    385 } // namespace std
    386 
    387 #endif /* _STL_NUMERIC_H */
    388