Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:09:50

0001 /// \file
0002 // Range v3 library
0003 //
0004 //  Copyright Eric Niebler 2013-present
0005 //  Copyright Gonzalo Brito Gadeschi 2014
0006 //
0007 //  Use, modification and distribution is subject to the
0008 //  Boost Software License, Version 1.0. (See accompanying
0009 //  file LICENSE_1_0.txt or copy at
0010 //  http://www.boost.org/LICENSE_1_0.txt)
0011 //
0012 // Project home: https://github.com/ericniebler/range-v3
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     /// \addtogroup group-numerics
0036     /// @{
0037     // clang-format off
0038     /// \concept inner_product_constraints_
0039     /// \brief The \c inner_product_constraints_ concept
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     /// \concept inner_product_constraints
0067     /// \brief The \c inner_product_constraints concept
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     // clang-format on
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 } // namespace ranges
0157 
0158 #include <range/v3/detail/epilogue.hpp>
0159 
0160 #endif