1 // Copyright 2009-2014 Neil Groves. 2 // Distributed under the Boost Software License, Version 1.0. (See 3 // accompanying file LICENSE_1_0.txt or copy at 4 // http://www.boost.org/LICENSE_1_0.txt) 5 // 6 // Copyright 2006 Thorsten Ottosen. 7 // Distributed under the Boost Software License, Version 1.0. (See 8 // accompanying file LICENSE_1_0.txt or copy at 9 // http://www.boost.org/LICENSE_1_0.txt) 10 // 11 // Copyright 2004 Eric Niebler. 12 // Distributed under the Boost Software License, Version 1.0. (See 13 // accompanying file LICENSE_1_0.txt or copy at 14 // http://www.boost.org/LICENSE_1_0.txt) 15 // 16 // Contains range-based versions of the numeric std algorithms 17 // 18 #if defined(_MSC_VER) 19 #pragma once 20 #endif 21 22 #ifndef BOOST_RANGE_NUMERIC_HPP 23 #define BOOST_RANGE_NUMERIC_HPP 24 25 #include <boost/config.hpp> 26 #include <boost/assert.hpp> 27 #include <boost/range/begin.hpp> 28 #include <boost/range/end.hpp> 29 #include <boost/range/category.hpp> 30 #include <boost/range/concepts.hpp> 31 #include <boost/range/distance.hpp> 32 #include <boost/range/size.hpp> 33 #include <numeric> 34 35 36 namespace boost 37 { 38 template<class SinglePassRange, class Value> accumulate(const SinglePassRange & rng,Value init)39 inline Value accumulate(const SinglePassRange& rng, Value init) 40 { 41 BOOST_RANGE_CONCEPT_ASSERT(( 42 SinglePassRangeConcept<const SinglePassRange>)); 43 44 return std::accumulate(boost::begin(rng), boost::end(rng), init); 45 } 46 47 template<class SinglePassRange, class Value, class BinaryOperation> accumulate(const SinglePassRange & rng,Value init,BinaryOperation op)48 inline Value accumulate(const SinglePassRange& rng, Value init, 49 BinaryOperation op) 50 { 51 BOOST_RANGE_CONCEPT_ASSERT(( 52 SinglePassRangeConcept<const SinglePassRange> )); 53 54 return std::accumulate(boost::begin(rng), boost::end(rng), init, op); 55 } 56 57 namespace range_detail 58 { 59 template<class SinglePassRange1, class SinglePassRange2> inner_product_precondition(const SinglePassRange1 &,const SinglePassRange2 &,std::input_iterator_tag,std::input_iterator_tag)60 inline bool inner_product_precondition( 61 const SinglePassRange1&, 62 const SinglePassRange2&, 63 std::input_iterator_tag, 64 std::input_iterator_tag) 65 { 66 return true; 67 } 68 69 template<class SinglePassRange1, class SinglePassRange2> inner_product_precondition(const SinglePassRange1 & rng1,const SinglePassRange2 & rng2,std::forward_iterator_tag,std::forward_iterator_tag)70 inline bool inner_product_precondition( 71 const SinglePassRange1& rng1, 72 const SinglePassRange2& rng2, 73 std::forward_iterator_tag, 74 std::forward_iterator_tag) 75 { 76 return boost::size(rng2) >= boost::size(rng1); 77 } 78 79 } // namespace range_detail 80 81 template< 82 class SinglePassRange1, 83 class SinglePassRange2, 84 class Value 85 > inner_product(const SinglePassRange1 & rng1,const SinglePassRange2 & rng2,Value init)86 inline Value inner_product( 87 const SinglePassRange1& rng1, 88 const SinglePassRange2& rng2, 89 Value init) 90 { 91 BOOST_RANGE_CONCEPT_ASSERT(( 92 SinglePassRangeConcept<const SinglePassRange1>)); 93 94 BOOST_RANGE_CONCEPT_ASSERT(( 95 SinglePassRangeConcept<const SinglePassRange2>)); 96 97 BOOST_ASSERT( 98 range_detail::inner_product_precondition( 99 rng1, rng2, 100 typename range_category<const SinglePassRange1>::type(), 101 typename range_category<const SinglePassRange2>::type())); 102 103 return std::inner_product( 104 boost::begin(rng1), boost::end(rng1), 105 boost::begin(rng2), init); 106 } 107 108 template< 109 class SinglePassRange1, 110 class SinglePassRange2, 111 class Value, 112 class BinaryOperation1, 113 class BinaryOperation2 114 > inner_product(const SinglePassRange1 & rng1,const SinglePassRange2 & rng2,Value init,BinaryOperation1 op1,BinaryOperation2 op2)115 inline Value inner_product( 116 const SinglePassRange1& rng1, 117 const SinglePassRange2& rng2, 118 Value init, 119 BinaryOperation1 op1, 120 BinaryOperation2 op2) 121 { 122 BOOST_RANGE_CONCEPT_ASSERT(( 123 SinglePassRangeConcept<const SinglePassRange1>)); 124 125 BOOST_RANGE_CONCEPT_ASSERT(( 126 SinglePassRangeConcept<const SinglePassRange2>)); 127 128 BOOST_ASSERT( 129 range_detail::inner_product_precondition( 130 rng1, rng2, 131 typename range_category<const SinglePassRange1>::type(), 132 typename range_category<const SinglePassRange2>::type())); 133 134 return std::inner_product( 135 boost::begin(rng1), boost::end(rng1), 136 boost::begin(rng2), init, op1, op2); 137 } 138 139 template<class SinglePassRange, class OutputIterator> partial_sum(const SinglePassRange & rng,OutputIterator result)140 inline OutputIterator partial_sum(const SinglePassRange& rng, 141 OutputIterator result) 142 { 143 BOOST_RANGE_CONCEPT_ASSERT(( 144 SinglePassRangeConcept<const SinglePassRange>)); 145 146 return std::partial_sum(boost::begin(rng), boost::end(rng), result); 147 } 148 149 template<class SinglePassRange, class OutputIterator, class BinaryOperation> partial_sum(const SinglePassRange & rng,OutputIterator result,BinaryOperation op)150 inline OutputIterator partial_sum( 151 const SinglePassRange& rng, 152 OutputIterator result, 153 BinaryOperation op) 154 { 155 BOOST_RANGE_CONCEPT_ASSERT(( 156 SinglePassRangeConcept<const SinglePassRange>)); 157 158 return std::partial_sum(boost::begin(rng), boost::end(rng), result, op); 159 } 160 161 template<class SinglePassRange, class OutputIterator> adjacent_difference(const SinglePassRange & rng,OutputIterator result)162 inline OutputIterator adjacent_difference( 163 const SinglePassRange& rng, 164 OutputIterator result) 165 { 166 BOOST_RANGE_CONCEPT_ASSERT(( 167 SinglePassRangeConcept<const SinglePassRange>)); 168 169 return std::adjacent_difference(boost::begin(rng), boost::end(rng), 170 result); 171 } 172 173 template<class SinglePassRange, class OutputIterator, class BinaryOperation> adjacent_difference(const SinglePassRange & rng,OutputIterator result,BinaryOperation op)174 inline OutputIterator adjacent_difference( 175 const SinglePassRange& rng, 176 OutputIterator result, 177 BinaryOperation op) 178 { 179 BOOST_RANGE_CONCEPT_ASSERT(( 180 SinglePassRangeConcept<const SinglePassRange>)); 181 182 return std::adjacent_difference(boost::begin(rng), boost::end(rng), 183 result, op); 184 } 185 186 } // namespace boost 187 188 #endif 189