Arene Base
Fundamental Utilities For Safety Critical C++
Loading...
Searching...
No Matches
inner_product.hpp
Go to the documentation of this file.
1// parasoft-begin-suppress AUTOSAR-A2_8_1-a "False positive: also defines std::inner_product"
2
3// Copyright 2026, Toyota Motor Corporation
4//
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
7#ifndef INCLUDE_GUARD_ARENE_BASE_STDLIB_INCLUDE_STDLIB_DETAIL_INNER_PRODUCT_HPP_
8#define INCLUDE_GUARD_ARENE_BASE_STDLIB_INCLUDE_STDLIB_DETAIL_INNER_PRODUCT_HPP_
9
10// parasoft-begin-suppress CERT_CPP-DCL58-a-2 "Part of a standard library implementation"
11// parasoft-begin-suppress AUTOSAR-A17_6_1-a-2 "Part of a standard library implementation"
12// parasoft-begin-suppress AUTOSAR-M2_10_1-a-2 "Similar names permitted by M2-10-1 Permit #1"
13
14// IWYU pragma: private, include <numeric>
15// IWYU pragma: friend "stdlib_detail/.*"
16//
17#include "arene/base/algorithm/detail/generalized_transform_reduce.hpp"
18#include "arene/base/algorithm/detail/traits.hpp"
19#include "arene/base/constraints.hpp"
20#include "arene/base/stdlib_choice/enable_if.hpp"
21#include "arene/base/stdlib_choice/is_assignable.hpp"
22#include "arene/base/stdlib_choice/is_move_constructible.hpp"
23#include "arene/base/stdlib_choice/move.hpp"
24#include "arene/base/stdlib_choice/multiplies.hpp"
25#include "arene/base/stdlib_choice/plus.hpp"
26#include "arene/base/type_traits/is_copyable.hpp"
27#include "arene/base/type_traits/is_invocable.hpp"
28#include "arene/base/type_traits/iterator_category_traits.hpp"
29
30namespace std {
32
33/// @brief reduce value policy for a C++14 compliant implementation
34/// @tparam Value accumulator value type
35///
36/// This reduce value policy has an @c access function that does *not* @c
37/// std::move the accumulator, it simply provides a reference.
38/// The @c assign function is equivalent to @c operator=.
39///
40/// The policy @c value is simply @c Value unchanged.
41template <class Value>
43 public:
44 /// @brief value type to use in the underlying implementation function
45 using value_type = Value;
46
47 /// @brief generalized assignment
48 /// @tparam Result result type
49 /// @param acc reference to the accumulator
50 /// @param result value to assign
51 ///
52 /// Update @c acc with @c result with the @c value_type assignment
53 /// operation.
54 ///
55 // parasoft-begin-suppress AUTOSAR-A8_4_8-a "'acc' is a reference to the
56 // assigned value and must be passed in as a parameter"
57 template <class Result>
58 static constexpr auto assign(value_type& acc, Result&& result) noexcept(
60 ) -> void {
61 acc = std::forward<Result>(result);
62 }
63 // parasoft-end-suppress AUTOSAR-A8_4_8-a
64
65 /// @brief generalized access
66 /// @param acc lvalue reference to the accumulator
67 /// @return <c> acc </c>
68 static constexpr auto access(value_type& acc) noexcept -> Value& { return acc; }
69 /// @brief generalized access
70 /// @param acc rvalue reference to the accumulator
71 /// @return <c> move(acc) </c>
72 static constexpr auto access(value_type&& acc) noexcept -> Value&& { return std::move(acc); }
73};
74
75} // namespace inner_product_detail
76
77// parasoft-begin-suppress AUTOSAR-M3_3_2-a "False positive: inline function used in multiple translation units"
78/// @brief computes the inner product of two ranges of elements
79/// @tparam InputIt1 type of the iterator for the first range
80/// @tparam InputIt2 type of the iterator for the second range
81/// @tparam Value type of the accumulated value
82/// @tparam Plus type of the addition operation
83/// @tparam Multiplies type of the multiplication operation
84/// @param first1 iterator to the beginning of the first range
85/// @param last1 iterator to one past the end of the first range
86/// @param first2 iterator to the beginning of the second range
87/// @param init initial value to start with
88/// @param plus binary function object used to reduce transformed elements
89/// to a single value
90/// @param multiplies binary function object applied to each pair of elements
91/// of the input ranges
92///
93/// @return Initializes the accumulator @c acc (of type @c Value) with the
94/// initial value @c init and then modifies it with the expression
95/// <c> acc = plus(acc, multiplies(*i1, *i2)) </c> for every iterator
96/// @c i1 in the range <c> [first1, last1) </c> in order and its
97/// corresponding iterator @c i2 in the range beginning at @c first2.
98///
99/// @pre <c> [first2, first2 + distance(first1, last1)) </c> is a valid range
100/// @pre @c plus does not invalidate subranges, nor modify elements in the
101/// ranges <c> [first1, last1) </c> and
102/// <c> [first2, first2 + distance(first1, last1)) </c>
103/// @pre @c multiplies does not invalidate subranges, nor modify elements in the
104/// ranges <c> [first1, last1) </c> and
105/// <c> [first2, first2 + distance(first1, last1)) </c>
106///
107/// @note Constraints <br>
108/// * @c InputIt1 must satisfy the input iterator requirements
109/// * @c InputIt2 must satisfy the input iterator requirements
110/// * @c Value is copy constructible
111/// * @c Value is copy assignable
112/// * <c> multiplies(*first1, *first2) </c> is a valid expression
113/// * <c> plus(init, multiplies(*first1, *first2)) </c> is assignable
114/// to @c Value
115///
116/// @note Complexity <br>
117/// O(N) applications of @c plus and @c multiplies, where
118/// <c> N = distance(first1, last1) </c>.
119///
120/// @note @c inner_product always performs the operations in the order given.
121///
122template <
123 class InputIt1,
124 class InputIt2,
125 class Value,
126 class Plus,
127 class Multiplies,
134 Value&,
136 Plus&,
137 Value&,
139 Multiplies&,
142 >
143 >
144 >::value>> = nullptr>
181
182/// @brief computes the inner product of two ranges of elements
183/// @tparam InputIt1 type of the iterator for the first range
184/// @tparam InputIt2 type of the iterator for the second range
185/// @tparam Value type of the accumulated value
186/// @param first1 iterator to the beginning of the first range
187/// @param last1 iterator to one past the end of the first range
188/// @param first2 iterator to the beginning of the second range
189/// @param init initial value to start with
190///
191/// @return Initializes the accumulator @c acc (of type @c Value) with the
192/// initial value @c init and then modifies it with the expression
193/// <c> acc = plus(acc, multiplies(*i1, *i2)) </c> for every iterator
194/// @c i1 in the range <c> [first1, last1) </c> in order and its
195/// corresponding iterator @c i2 in the range beginning at @c first2.
196///
197/// @pre <c> [first2, first2 + distance(first1, last1)) </c> is a valid range
198/// @pre binary @c operator+ does not invalidate subranges, nor modify elements
199/// in the ranges <c> [first1, last1) </c> and
200/// <c> [first2, first2 + distance(first1, last1)) </c>
201/// @pre binary @c operator* does not invalidate subranges, nor modify elements
202/// in the ranges <c> [first1, last1) </c> and
203/// <c> [first2, first2 + distance(first1, last1)) </c>
204///
205/// @note Constraints <br>
206/// * @c InputIt1 must satisfy the input iterator requirements
207/// * @c InputIt2 must satisfy the input iterator requirements
208/// * @c Value is copy constructible
209/// * @c Value is copy assignable
210/// * <c> *first1 * *first2 </c> is a valid expression
211/// * <c> init + multiplies(*first1, *first2) </c> is assignable
212/// to @c Value
213///
214/// @note Complexity <br>
215/// O(N) applications of @c plus and @c multiplies, where
216/// <c> N = distance(first1, last1) </c>.
217///
218/// @note @c inner_product always performs the operations in the order given.
219///
220template <
221 class InputIt1,
222 class InputIt2,
223 class Value,
229 Value&,
231 plus<>&,
232 Value&,
234 multiplies<>&,
241 Value init
242) noexcept( //
243 noexcept(std::inner_product(
244 std::declval<InputIt1&&>(),
245 std::declval<InputIt1&&>(),
246 std::declval<InputIt2&&>(),
247 std::declval<Value&&>(),
248 std::declval<std::plus<>&&>(),
249 std::declval<std::multiplies<>&&>()
250 ))
251) -> Value {
252 return std::inner_product(
253 std::move(first1),
254 std::move(last1),
255 std::move(first2),
256 std::move(init),
257 std::plus<>{},
258 std::multiplies<>{}
259 );
260}
261
262} // namespace std
263
264#endif // INCLUDE_GUARD_ARENE_BASE_STDLIB_INCLUDE_STDLIB_DETAIL_INNER_PRODUCT_HPP_
reduce value policy for a C++14 compliant implementation
Definition inner_product.hpp:42
static constexpr auto assign(value_type &acc, Result &&result) noexcept(std::is_nothrow_assignable< Value &, Result && >::value) -> void
generalized assignment
Definition inner_product.hpp:58
static constexpr auto access(value_type &&acc) noexcept -> Value &&
generalized access
Definition inner_product.hpp:72
static constexpr auto access(value_type &acc) noexcept -> Value &
generalized access
Definition inner_product.hpp:68
Definition inner_product.hpp:31
constexpr auto operator()(::arene::base::result< void, E > const &value) const noexcept(noexcept(hash< E >{}(std::declval< E const & >()))) -> std::size_t
Calculate the hash of a result.
Definition result.hpp:1827