summaryrefslogtreecommitdiff
path: root/boost/range/numeric.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/range/numeric.hpp')
-rw-r--r--boost/range/numeric.hpp192
1 files changed, 131 insertions, 61 deletions
diff --git a/boost/range/numeric.hpp b/boost/range/numeric.hpp
index bfd1049407..d1510cdef1 100644
--- a/boost/range/numeric.hpp
+++ b/boost/range/numeric.hpp
@@ -1,14 +1,8 @@
-///////////////////////////////////////////////////////////////////////////////
-/// \file algorithm.hpp
-/// Contains range-based versions of the std algorithms
-//
-/////////////////////////////////////////////////////////////////////////////
-// Copyright 2009 Neil Groves.
+// Copyright 2009-2014 Neil Groves.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
-
// Copyright 2006 Thorsten Ottosen.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -18,8 +12,10 @@
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-
-#if defined(_MSC_VER) && _MSC_VER >= 1000
+//
+// Contains range-based versions of the numeric std algorithms
+//
+#if defined(_MSC_VER)
#pragma once
#endif
@@ -30,89 +26,163 @@
#include <boost/assert.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
+#include <boost/range/category.hpp>
#include <boost/range/concepts.hpp>
#include <boost/range/distance.hpp>
+#include <boost/range/size.hpp>
#include <numeric>
namespace boost
{
- template< class SinglePassRange, class Value >
- inline Value accumulate( const SinglePassRange& rng, Value init )
+ template<class SinglePassRange, class Value>
+ inline Value accumulate(const SinglePassRange& rng, Value init)
{
- BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
- return std::accumulate( boost::begin(rng), boost::end(rng), init );
+ BOOST_RANGE_CONCEPT_ASSERT((
+ SinglePassRangeConcept<const SinglePassRange>));
+
+ return std::accumulate(boost::begin(rng), boost::end(rng), init);
}
- template< class SinglePassRange, class Value, class BinaryOperation >
- inline Value accumulate( const SinglePassRange& rng, Value init, BinaryOperation op )
+ template<class SinglePassRange, class Value, class BinaryOperation>
+ inline Value accumulate(const SinglePassRange& rng, Value init,
+ BinaryOperation op)
{
- BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
- return std::accumulate( boost::begin(rng), boost::end(rng), init, op );
- }
+ BOOST_RANGE_CONCEPT_ASSERT((
+ SinglePassRangeConcept<const SinglePassRange> ));
+ return std::accumulate(boost::begin(rng), boost::end(rng), init, op);
+ }
- template< class SinglePassRange1, class SinglePassRange2, class Value >
- inline Value inner_product( const SinglePassRange1& rng1, const SinglePassRange2& rng2, Value init )
+ namespace range_detail
+ {
+ template<class SinglePassRange1, class SinglePassRange2>
+ inline bool inner_product_precondition(
+ const SinglePassRange1&,
+ const SinglePassRange2&,
+ std::input_iterator_tag,
+ std::input_iterator_tag)
+ {
+ return true;
+ }
+
+ template<class SinglePassRange1, class SinglePassRange2>
+ inline bool inner_product_precondition(
+ const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2,
+ std::forward_iterator_tag,
+ std::forward_iterator_tag)
+ {
+ return boost::size(rng2) >= boost::size(rng1);
+ }
+
+ } // namespace range_detail
+
+ template<
+ class SinglePassRange1,
+ class SinglePassRange2,
+ class Value
+ >
+ inline Value inner_product(
+ const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2,
+ Value init)
{
- BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
- BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
- BOOST_ASSERT( boost::distance(rng2) >= boost::distance(rng1) );
- return std::inner_product( boost::begin(rng1), boost::end(rng1),
- boost::begin(rng2), init );
+ BOOST_RANGE_CONCEPT_ASSERT((
+ SinglePassRangeConcept<const SinglePassRange1>));
+
+ BOOST_RANGE_CONCEPT_ASSERT((
+ SinglePassRangeConcept<const SinglePassRange2>));
+
+ BOOST_ASSERT(
+ range_detail::inner_product_precondition(
+ rng1, rng2,
+ typename range_category<const SinglePassRange1>::type(),
+ typename range_category<const SinglePassRange2>::type()));
+
+ return std::inner_product(
+ boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), init);
}
- template< class SinglePassRange1,
- class SinglePassRange2,
- class Value,
- class BinaryOperation1, class BinaryOperation2 >
- inline Value inner_product( const SinglePassRange1& rng1, const SinglePassRange2& rng2,
- Value init,
- BinaryOperation1 op1, BinaryOperation2 op2 )
+ template<
+ class SinglePassRange1,
+ class SinglePassRange2,
+ class Value,
+ class BinaryOperation1,
+ class BinaryOperation2
+ >
+ inline Value inner_product(
+ const SinglePassRange1& rng1,
+ const SinglePassRange2& rng2,
+ Value init,
+ BinaryOperation1 op1,
+ BinaryOperation2 op2)
{
- BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
- BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
- BOOST_ASSERT( boost::distance(rng2) >= boost::distance(rng1) );
+ BOOST_RANGE_CONCEPT_ASSERT((
+ SinglePassRangeConcept<const SinglePassRange1>));
+
+ BOOST_RANGE_CONCEPT_ASSERT((
+ SinglePassRangeConcept<const SinglePassRange2>));
+
+ BOOST_ASSERT(
+ range_detail::inner_product_precondition(
+ rng1, rng2,
+ typename range_category<const SinglePassRange1>::type(),
+ typename range_category<const SinglePassRange2>::type()));
- return std::inner_product( boost::begin(rng1), boost::end(rng1),
- boost::begin(rng2), init, op1, op2 );
+ return std::inner_product(
+ boost::begin(rng1), boost::end(rng1),
+ boost::begin(rng2), init, op1, op2);
}
- template< class SinglePassRange, class OutputIterator >
- inline OutputIterator partial_sum ( const SinglePassRange& rng,
- OutputIterator result )
+ template<class SinglePassRange, class OutputIterator>
+ inline OutputIterator partial_sum(const SinglePassRange& rng,
+ OutputIterator result)
{
- BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
- return std::partial_sum( boost::begin(rng), boost::end(rng), result );
+ BOOST_RANGE_CONCEPT_ASSERT((
+ SinglePassRangeConcept<const SinglePassRange>));
+
+ return std::partial_sum(boost::begin(rng), boost::end(rng), result);
}
- template< class SinglePassRange, class OutputIterator, class BinaryOperation >
- inline OutputIterator partial_sum ( const SinglePassRange& rng, OutputIterator result,
- BinaryOperation op )
+ template<class SinglePassRange, class OutputIterator, class BinaryOperation>
+ inline OutputIterator partial_sum(
+ const SinglePassRange& rng,
+ OutputIterator result,
+ BinaryOperation op)
{
- BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
- return std::partial_sum( boost::begin(rng), boost::end(rng), result, op );
+ BOOST_RANGE_CONCEPT_ASSERT((
+ SinglePassRangeConcept<const SinglePassRange>));
+
+ return std::partial_sum(boost::begin(rng), boost::end(rng), result, op);
}
- template< class SinglePassRange, class OutputIterator >
- inline OutputIterator adjacent_difference ( const SinglePassRange& rng,
- OutputIterator result )
+ template<class SinglePassRange, class OutputIterator>
+ inline OutputIterator adjacent_difference(
+ const SinglePassRange& rng,
+ OutputIterator result)
{
- BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange> ));
- return std::adjacent_difference( boost::begin(rng), boost::end(rng),
- result );
+ BOOST_RANGE_CONCEPT_ASSERT((
+ SinglePassRangeConcept<const SinglePassRange>));
+
+ return std::adjacent_difference(boost::begin(rng), boost::end(rng),
+ result);
}
- template< class SinglePassRange, class OutputIterator, class BinaryOperation >
- inline OutputIterator adjacent_difference ( const SinglePassRange& rng,
- OutputIterator result,
- BinaryOperation op )
+ template<class SinglePassRange, class OutputIterator, class BinaryOperation>
+ inline OutputIterator adjacent_difference(
+ const SinglePassRange& rng,
+ OutputIterator result,
+ BinaryOperation op)
{
- BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange> ));
- return std::adjacent_difference( boost::begin(rng), boost::end(rng),
- result, op );
+ BOOST_RANGE_CONCEPT_ASSERT((
+ SinglePassRangeConcept<const SinglePassRange>));
+
+ return std::adjacent_difference(boost::begin(rng), boost::end(rng),
+ result, op);
}
-}
+} // namespace boost
#endif