Horizon
inner_product.hpp
Go to the documentation of this file.
1 // Range v3 library
3 //
4 // Copyright Eric Niebler 2013-present
5 // Copyright Gonzalo Brito Gadeschi 2014
6 //
7 // Use, modification and distribution is subject to the
8 // Boost Software License, Version 1.0. (See accompanying
9 // file LICENSE_1_0.txt or copy at
10 // http://www.boost.org/LICENSE_1_0.txt)
11 //
12 // Project home: https://github.com/ericniebler/range-v3
13 //
14 #ifndef RANGES_V3_NUMERIC_INNER_PRODUCT_HPP
15 #define RANGES_V3_NUMERIC_INNER_PRODUCT_HPP
16 
17 #include <meta/meta.hpp>
18 
29 #include <range/v3/utility/static_const.hpp>
30 
31 #include <range/v3/detail/prologue.hpp>
32 
33 namespace ranges
34 {
37  // clang-format off
40  template(typename I1, typename I2, typename T, typename BOp1, typename BOp2,
41  typename P1, typename P2)(
42  concept (inner_product_constraints_)(I1, I2, T, BOp1, BOp2, P1, P2),
43  invocable<P1&, iter_value_t<I1>> AND
44  invocable<P2&, iter_value_t<I2>> AND
45  invocable<
46  BOp2&,
47  invoke_result_t<P1&, iter_value_t<I1>>,
48  invoke_result_t<P2&, iter_value_t<I2>>> AND
49  invocable<
50  BOp1&,
51  T,
52  invoke_result_t<
53  BOp2&,
54  invoke_result_t<P1&, iter_value_t<I1>>,
55  invoke_result_t<P2&, iter_value_t<I2>>>> AND
56  assignable_from<
57  T&,
58  invoke_result_t<
59  BOp1&,
60  T,
61  invoke_result_t<
62  BOp2&,
63  invoke_result_t<P1&, iter_value_t<I1>>,
64  invoke_result_t<P2&, iter_value_t<I2>>>>>
65  );
68  template<typename I1, typename I2, typename T, typename BOp1 = plus,
69  typename BOp2 = multiplies, typename P1 = identity, typename P2 = identity>
71  input_iterator<I1> &&
72  input_iterator<I2> &&
73  CPP_concept_ref(ranges::inner_product_constraints_, I1, I2, T, BOp1, BOp2, P1, P2);
74  // clang-format on
75 
77  {
78  template(typename I1, typename S1, typename I2, typename S2, typename T,
79  typename BOp1 = plus, typename BOp2 = multiplies, typename P1 = identity,
80  typename P2 = identity)(
81  requires sentinel_for<S1, I1> AND sentinel_for<S2, I2> AND
82  inner_product_constraints<I1, I2, T, BOp1, BOp2, P1, P2>)
83  T operator()(I1 begin1, S1 end1, I2 begin2, S2 end2, T init,
84  BOp1 bop1 = BOp1{}, BOp2 bop2 = BOp2{}, P1 proj1 = P1{},
85  P2 proj2 = P2{}) const
86  {
87  for(; begin1 != end1 && begin2 != end2; ++begin1, ++begin2)
88  init =
89  invoke(bop1,
90  init,
91  invoke(bop2, invoke(proj1, *begin1), invoke(proj2, *begin2)));
92  return init;
93  }
94 
95  template(typename I1, typename S1, typename I2, typename T, typename BOp1 = plus,
96  typename BOp2 = multiplies, typename P1 = identity,
97  typename P2 = identity)(
98  requires sentinel_for<S1, I1> AND
99  inner_product_constraints<I1, I2, T, BOp1, BOp2, P1, P2>)
100  T operator()(I1 begin1, S1 end1, I2 begin2, T init, BOp1 bop1 = BOp1{},
101  BOp2 bop2 = BOp2{}, P1 proj1 = P1{}, P2 proj2 = P2{}) const
102  {
103  return (*this)(std::move(begin1),
104  std::move(end1),
105  std::move(begin2),
106  unreachable,
107  std::move(init),
108  std::move(bop1),
109  std::move(bop2),
110  std::move(proj1),
111  std::move(proj2));
112  }
113 
114  template(typename Rng1, typename I2Ref, typename T, typename BOp1 = plus,
115  typename BOp2 = multiplies, typename P1 = identity,
116  typename P2 = identity, typename I1 = iterator_t<Rng1>,
117  typename I2 = uncvref_t<I2Ref>)(
118  requires range<Rng1> AND
119  inner_product_constraints<I1, I2, T, BOp1, BOp2, P1, P2>)
120  T operator()(Rng1 && rng1, I2Ref && begin2, T init, BOp1 bop1 = BOp1{},
121  BOp2 bop2 = BOp2{}, P1 proj1 = P1{}, P2 proj2 = P2{}) const
122  {
123  return (*this)(begin(rng1),
124  end(rng1),
125  static_cast<I2Ref &&>(begin2),
126  std::move(init),
127  std::move(bop1),
128  std::move(bop2),
129  std::move(proj1),
130  std::move(proj2));
131  }
132 
133  template(typename Rng1, typename Rng2, typename T, typename BOp1 = plus,
134  typename BOp2 = multiplies, typename P1 = identity,
135  typename P2 = identity, typename I1 = iterator_t<Rng1>,
136  typename I2 = iterator_t<Rng2>)(
137  requires range<Rng1> AND range<Rng2> AND
138  inner_product_constraints<I1, I2, T, BOp1, BOp2, P1, P2>)
139  T operator()(Rng1 && rng1, Rng2 && rng2, T init, BOp1 bop1 = BOp1{},
140  BOp2 bop2 = BOp2{}, P1 proj1 = P1{}, P2 proj2 = P2{}) const
141  {
142  return (*this)(begin(rng1),
143  end(rng1),
144  begin(rng2),
145  end(rng2),
146  std::move(init),
147  std::move(bop1),
148  std::move(bop2),
149  std::move(proj1),
150  std::move(proj2));
151  }
152  };
153 
156 } // namespace ranges
157 
158 #include <range/v3/detail/epilogue.hpp>
159 
160 #endif
CPP_concept invocable
\concept invocable
Definition: concepts.hpp:48
CPP_concept inner_product_constraints
\concept inner_product_constraints
Definition: inner_product.hpp:70
decltype(begin(declval(Rng &))) iterator_t
Definition: access.hpp:698
RANGES_INLINE_VARIABLE(detail::to_container_fn< detail::from_range< std::vector >>, to_vector) template< template< typename... > class ContT > auto to(RANGES_HIDDEN_DETAIL(detail
For initializing a container of the specified type with the elements of an Range.
Definition: conversion.hpp:399
typename Fn::template invoke< Args... > invoke
Evaluate the invocable Fn with the arguments Args.
Definition: meta.hpp:541
std::integral_constant< decltype(T::type::value *U::type::value), T::type::value *U::type::value > multiplies
An integral constant wrapper around the result of multiplying the two wrapped integers T::type::value...
Definition: meta.hpp:211
std::integral_constant< decltype(T::type::value+U::type::value), T::type::value+U::type::value > plus
An integral constant wrapper around the result of adding the two wrapped integers T::type::value and ...
Definition: meta.hpp:197
Tiny meta-programming library.
Definition: identity.hpp:25
Definition: inner_product.hpp:77