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 2004
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 // Implementation based on the code in libc++
0015 //   http://http://libcxx.llvm.org/
0016 
0017 #ifndef RANGES_V3_NUMERIC_ADJACENT_DIFFERENCE_HPP
0018 #define RANGES_V3_NUMERIC_ADJACENT_DIFFERENCE_HPP
0019 
0020 #include <meta/meta.hpp>
0021 
0022 #include <range/v3/algorithm/result_types.hpp>
0023 #include <range/v3/functional/arithmetic.hpp>
0024 #include <range/v3/functional/identity.hpp>
0025 #include <range/v3/functional/invoke.hpp>
0026 #include <range/v3/iterator/concepts.hpp>
0027 #include <range/v3/iterator/traits.hpp>
0028 #include <range/v3/iterator/unreachable_sentinel.hpp>
0029 #include <range/v3/range/access.hpp>
0030 #include <range/v3/range/concepts.hpp>
0031 #include <range/v3/range/dangling.hpp>
0032 #include <range/v3/range/traits.hpp>
0033 #include <range/v3/utility/static_const.hpp>
0034 
0035 #include <range/v3/detail/prologue.hpp>
0036 
0037 namespace ranges
0038 {
0039     /// \addtogroup group-numerics
0040     /// @{
0041     // clang-format off
0042     /// \concept differenceable_
0043     /// \brief The \c differenceable_ concept
0044     template(typename I, typename O, typename BOp, typename P)(
0045     concept (differenceable_)(I, O, BOp, P),
0046         invocable<P&, iter_value_t<I>> AND
0047         copy_constructible<uncvref_t<invoke_result_t<P&, iter_value_t<I>>>> AND
0048         movable<uncvref_t<invoke_result_t<P&, iter_value_t<I>>>> AND
0049         output_iterator<O, invoke_result_t<P&, iter_value_t<I>>> AND
0050         invocable<
0051             BOp&,
0052             invoke_result_t<
0053                 P&,
0054                 iter_value_t<I>>,
0055                 invoke_result_t<P&, iter_value_t<I>>> AND
0056         output_iterator<
0057             O,
0058             invoke_result_t<
0059                 BOp&,
0060                 invoke_result_t<P&, iter_value_t<I>>,
0061                 invoke_result_t<P&, iter_value_t<I>>>>);
0062 
0063     /// \concept differenceable
0064     /// \brief The \c differenceable concept
0065     template<typename I, typename O, typename BOp = minus, typename P = identity>
0066     CPP_concept differenceable =
0067         input_iterator<I> &&
0068         CPP_concept_ref(ranges::differenceable_, I, O, BOp, P);
0069     // clang-format on
0070 
0071     template<typename I, typename O>
0072     using adjacent_difference_result = detail::in_out_result<I, O>;
0073 
0074     struct adjacent_difference_fn
0075     {
0076         template(typename I, typename S, typename O, typename S2, typename BOp = minus,
0077                  typename P = identity)(
0078             requires sentinel_for<S, I> AND sentinel_for<S2, O> AND
0079                 differenceable<I, O, BOp, P>)
0080         adjacent_difference_result<I, O> operator()(I first,
0081                                                     S last,
0082                                                     O result,
0083                                                     S2 end_result,
0084                                                     BOp bop = BOp{},
0085                                                     P proj = P{}) const
0086         {
0087             // BUGBUG think about the use of coerce here.
0088             using V = iter_value_t<I>;
0089             using X = invoke_result_t<P &, V>;
0090             coerce<V> v;
0091             coerce<X> x;
0092 
0093             if(first != last && result != end_result)
0094             {
0095                 auto t1(x(invoke(proj, v(*first))));
0096                 *result = t1;
0097                 for(++first, ++result; first != last && result != end_result;
0098                     ++first, ++result)
0099                 {
0100                     auto t2(x(invoke(proj, v(*first))));
0101                     *result = invoke(bop, t2, t1);
0102                     t1 = std::move(t2);
0103                 }
0104             }
0105             return {first, result};
0106         }
0107 
0108         template(typename I, typename S, typename O, typename BOp = minus,
0109                  typename P = identity)(
0110             requires sentinel_for<S, I> AND differenceable<I, O, BOp, P>)
0111         adjacent_difference_result<I, O> //
0112         operator()(I first, S last, O result, BOp bop = BOp{}, P proj = P{}) const
0113         {
0114             return (*this)(std::move(first),
0115                            std::move(last),
0116                            std::move(result),
0117                            unreachable,
0118                            std::move(bop),
0119                            std::move(proj));
0120         }
0121 
0122         template(typename Rng, typename ORef, typename BOp = minus, typename P = identity,
0123                  typename I = iterator_t<Rng>, typename O = uncvref_t<ORef>)(
0124             requires range<Rng> AND differenceable<I, O, BOp, P>)
0125         adjacent_difference_result<borrowed_iterator_t<Rng>, O> //
0126         operator()(Rng && rng, ORef && result, BOp bop = BOp{}, P proj = P{}) const
0127         {
0128             return (*this)(begin(rng),
0129                            end(rng),
0130                            static_cast<ORef &&>(result),
0131                            std::move(bop),
0132                            std::move(proj));
0133         }
0134 
0135         template(typename Rng, typename ORng, typename BOp = minus, typename P = identity,
0136                  typename I = iterator_t<Rng>, typename O = iterator_t<ORng>)(
0137             requires range<Rng> AND range<ORng> AND differenceable<I, O, BOp, P>)
0138         adjacent_difference_result<borrowed_iterator_t<Rng>, borrowed_iterator_t<ORng>>
0139         operator()(Rng && rng, ORng && result, BOp bop = BOp{}, P proj = P{}) const
0140         {
0141             return (*this)(begin(rng),
0142                            end(rng),
0143                            begin(result),
0144                            end(result),
0145                            std::move(bop),
0146                            std::move(proj));
0147         }
0148     };
0149 
0150     RANGES_INLINE_VARIABLE(adjacent_difference_fn, adjacent_difference)
0151     /// @}
0152 } // namespace ranges
0153 
0154 #include <range/v3/detail/epilogue.hpp>
0155 
0156 #endif