File indexing completed on 2025-01-18 10:09:50
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef RANGES_V3_NUMERIC_INNER_PRODUCT_HPP
0015 #define RANGES_V3_NUMERIC_INNER_PRODUCT_HPP
0016
0017 #include <meta/meta.hpp>
0018
0019 #include <range/v3/functional/arithmetic.hpp>
0020 #include <range/v3/functional/concepts.hpp>
0021 #include <range/v3/functional/identity.hpp>
0022 #include <range/v3/functional/invoke.hpp>
0023 #include <range/v3/iterator/concepts.hpp>
0024 #include <range/v3/iterator/traits.hpp>
0025 #include <range/v3/iterator/unreachable_sentinel.hpp>
0026 #include <range/v3/range/access.hpp>
0027 #include <range/v3/range/concepts.hpp>
0028 #include <range/v3/range/traits.hpp>
0029 #include <range/v3/utility/static_const.hpp>
0030
0031 #include <range/v3/detail/prologue.hpp>
0032
0033 namespace ranges
0034 {
0035
0036
0037
0038
0039
0040 template(typename I1, typename I2, typename T, typename BOp1, typename BOp2,
0041 typename P1, typename P2)(
0042 concept (inner_product_constraints_)(I1, I2, T, BOp1, BOp2, P1, P2),
0043 invocable<P1&, iter_value_t<I1>> AND
0044 invocable<P2&, iter_value_t<I2>> AND
0045 invocable<
0046 BOp2&,
0047 invoke_result_t<P1&, iter_value_t<I1>>,
0048 invoke_result_t<P2&, iter_value_t<I2>>> AND
0049 invocable<
0050 BOp1&,
0051 T,
0052 invoke_result_t<
0053 BOp2&,
0054 invoke_result_t<P1&, iter_value_t<I1>>,
0055 invoke_result_t<P2&, iter_value_t<I2>>>> AND
0056 assignable_from<
0057 T&,
0058 invoke_result_t<
0059 BOp1&,
0060 T,
0061 invoke_result_t<
0062 BOp2&,
0063 invoke_result_t<P1&, iter_value_t<I1>>,
0064 invoke_result_t<P2&, iter_value_t<I2>>>>>
0065 );
0066
0067
0068 template<typename I1, typename I2, typename T, typename BOp1 = plus,
0069 typename BOp2 = multiplies, typename P1 = identity, typename P2 = identity>
0070 CPP_concept inner_product_constraints =
0071 input_iterator<I1> &&
0072 input_iterator<I2> &&
0073 CPP_concept_ref(ranges::inner_product_constraints_, I1, I2, T, BOp1, BOp2, P1, P2);
0074
0075
0076 struct inner_product_fn
0077 {
0078 template(typename I1, typename S1, typename I2, typename S2, typename T,
0079 typename BOp1 = plus, typename BOp2 = multiplies, typename P1 = identity,
0080 typename P2 = identity)(
0081 requires sentinel_for<S1, I1> AND sentinel_for<S2, I2> AND
0082 inner_product_constraints<I1, I2, T, BOp1, BOp2, P1, P2>)
0083 T operator()(I1 begin1, S1 end1, I2 begin2, S2 end2, T init,
0084 BOp1 bop1 = BOp1{}, BOp2 bop2 = BOp2{}, P1 proj1 = P1{},
0085 P2 proj2 = P2{}) const
0086 {
0087 for(; begin1 != end1 && begin2 != end2; ++begin1, ++begin2)
0088 init =
0089 invoke(bop1,
0090 init,
0091 invoke(bop2, invoke(proj1, *begin1), invoke(proj2, *begin2)));
0092 return init;
0093 }
0094
0095 template(typename I1, typename S1, typename I2, typename T, typename BOp1 = plus,
0096 typename BOp2 = multiplies, typename P1 = identity,
0097 typename P2 = identity)(
0098 requires sentinel_for<S1, I1> AND
0099 inner_product_constraints<I1, I2, T, BOp1, BOp2, P1, P2>)
0100 T operator()(I1 begin1, S1 end1, I2 begin2, T init, BOp1 bop1 = BOp1{},
0101 BOp2 bop2 = BOp2{}, P1 proj1 = P1{}, P2 proj2 = P2{}) const
0102 {
0103 return (*this)(std::move(begin1),
0104 std::move(end1),
0105 std::move(begin2),
0106 unreachable,
0107 std::move(init),
0108 std::move(bop1),
0109 std::move(bop2),
0110 std::move(proj1),
0111 std::move(proj2));
0112 }
0113
0114 template(typename Rng1, typename I2Ref, typename T, typename BOp1 = plus,
0115 typename BOp2 = multiplies, typename P1 = identity,
0116 typename P2 = identity, typename I1 = iterator_t<Rng1>,
0117 typename I2 = uncvref_t<I2Ref>)(
0118 requires range<Rng1> AND
0119 inner_product_constraints<I1, I2, T, BOp1, BOp2, P1, P2>)
0120 T operator()(Rng1 && rng1, I2Ref && begin2, T init, BOp1 bop1 = BOp1{},
0121 BOp2 bop2 = BOp2{}, P1 proj1 = P1{}, P2 proj2 = P2{}) const
0122 {
0123 return (*this)(begin(rng1),
0124 end(rng1),
0125 static_cast<I2Ref &&>(begin2),
0126 std::move(init),
0127 std::move(bop1),
0128 std::move(bop2),
0129 std::move(proj1),
0130 std::move(proj2));
0131 }
0132
0133 template(typename Rng1, typename Rng2, typename T, typename BOp1 = plus,
0134 typename BOp2 = multiplies, typename P1 = identity,
0135 typename P2 = identity, typename I1 = iterator_t<Rng1>,
0136 typename I2 = iterator_t<Rng2>)(
0137 requires range<Rng1> AND range<Rng2> AND
0138 inner_product_constraints<I1, I2, T, BOp1, BOp2, P1, P2>)
0139 T operator()(Rng1 && rng1, Rng2 && rng2, T init, BOp1 bop1 = BOp1{},
0140 BOp2 bop2 = BOp2{}, P1 proj1 = P1{}, P2 proj2 = P2{}) const
0141 {
0142 return (*this)(begin(rng1),
0143 end(rng1),
0144 begin(rng2),
0145 end(rng2),
0146 std::move(init),
0147 std::move(bop1),
0148 std::move(bop2),
0149 std::move(proj1),
0150 std::move(proj2));
0151 }
0152 };
0153
0154 RANGES_INLINE_VARIABLE(inner_product_fn, inner_product)
0155
0156 }
0157
0158 #include <range/v3/detail/epilogue.hpp>
0159
0160 #endif