File indexing completed on 2025-12-17 10:23:59
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef RANGES_V3_ALGORITHM_TRANSFORM_HPP
0014 #define RANGES_V3_ALGORITHM_TRANSFORM_HPP
0015
0016 #include <utility>
0017
0018 #include <meta/meta.hpp>
0019
0020 #include <range/v3/range_fwd.hpp>
0021
0022 #include <range/v3/algorithm/result_types.hpp>
0023 #include <range/v3/functional/identity.hpp>
0024 #include <range/v3/functional/invoke.hpp>
0025 #include <range/v3/iterator/concepts.hpp>
0026 #include <range/v3/iterator/traits.hpp>
0027 #include <range/v3/iterator/unreachable_sentinel.hpp>
0028 #include <range/v3/range/access.hpp>
0029 #include <range/v3/range/concepts.hpp>
0030 #include <range/v3/range/dangling.hpp>
0031 #include <range/v3/range/traits.hpp>
0032 #include <range/v3/utility/static_const.hpp>
0033
0034 #include <range/v3/detail/prologue.hpp>
0035
0036 namespace ranges
0037 {
0038
0039
0040 template<typename I, typename O>
0041 using unary_transform_result = detail::in_out_result<I, O>;
0042
0043 template<typename I1, typename I2, typename O>
0044 using binary_transform_result = detail::in1_in2_out_result<I1, I2, O>;
0045
0046 RANGES_FUNC_BEGIN(transform)
0047
0048
0049
0050 template(typename I, typename S, typename O, typename F, typename P = identity)(
0051 requires input_iterator<I> AND sentinel_for<S, I> AND
0052 weakly_incrementable<O> AND copy_constructible<F> AND
0053 indirectly_writable<O, indirect_result_t<F &, projected<I, P>>>)
0054 constexpr unary_transform_result<I, O>
0055 RANGES_FUNC(transform)(I first, S last, O out, F fun, P proj = P{})
0056 {
0057 for(; first != last; ++first, ++out)
0058 *out = invoke(fun, invoke(proj, *first));
0059 return {first, out};
0060 }
0061
0062
0063 template(typename Rng, typename O, typename F, typename P = identity)(
0064 requires input_range<Rng> AND weakly_incrementable<O> AND
0065 copy_constructible<F> AND
0066 indirectly_writable<O, indirect_result_t<F &, projected<iterator_t<Rng>, P>>>)
0067 constexpr unary_transform_result<borrowed_iterator_t<Rng>, O>
0068 RANGES_FUNC(transform)(Rng && rng, O out, F fun, P proj = P{})
0069 {
0070 return (*this)(
0071 begin(rng), end(rng), std::move(out), std::move(fun), std::move(proj));
0072 }
0073
0074
0075
0076 template(typename I0,
0077 typename S0,
0078 typename I1,
0079 typename S1,
0080 typename O,
0081 typename F,
0082 typename P0 = identity,
0083 typename P1 = identity)(
0084 requires input_iterator<I0> AND sentinel_for<S0, I0> AND
0085 input_iterator<I1> AND sentinel_for<S1, I1> AND
0086 weakly_incrementable<O> AND copy_constructible<F> AND
0087 indirectly_writable<
0088 O,
0089 indirect_result_t<F &, projected<I0, P0>, projected<I1, P1>>>)
0090 constexpr binary_transform_result<I0, I1, O>
0091 RANGES_FUNC(transform)(I0 begin0,
0092 S0 end0,
0093 I1 begin1,
0094 S1 end1,
0095 O out,
0096 F fun,
0097 P0 proj0 = P0{},
0098 P1 proj1 = P1{})
0099 {
0100 for(; begin0 != end0 && begin1 != end1; ++begin0, ++begin1, ++out)
0101 *out = invoke(fun, invoke(proj0, *begin0), invoke(proj1, *begin1));
0102 return {begin0, begin1, out};
0103 }
0104
0105
0106 template(typename Rng0,
0107 typename Rng1,
0108 typename O,
0109 typename F,
0110 typename P0 = identity,
0111 typename P1 = identity)(
0112 requires input_range<Rng0> AND input_range<Rng1> AND
0113 weakly_incrementable<O> AND copy_constructible<F> AND
0114 indirectly_writable<
0115 O,
0116 indirect_result_t<F &,
0117 projected<iterator_t<Rng0>, P0>,
0118 projected<iterator_t<Rng1>, P1>>>)
0119 constexpr binary_transform_result<borrowed_iterator_t<Rng0>,
0120 borrowed_iterator_t<Rng1>,
0121 O>
0122 RANGES_FUNC(transform)(
0123 Rng0 && rng0, Rng1 && rng1, O out, F fun, P0 proj0 = P0{}, P1 proj1 = P1{})
0124 {
0125 return (*this)(begin(rng0),
0126 end(rng0),
0127 begin(rng1),
0128 end(rng1),
0129 std::move(out),
0130 std::move(fun),
0131 std::move(proj0),
0132 std::move(proj1));
0133 }
0134
0135
0136
0137 template(typename I0,
0138 typename S0,
0139 typename I1,
0140 typename O,
0141 typename F,
0142 typename P0 = identity,
0143 typename P1 = identity)(
0144 requires input_iterator<I0> AND sentinel_for<S0, I0> AND
0145 input_iterator<I1> AND weakly_incrementable<O> AND
0146 copy_constructible<F> AND
0147 indirectly_writable<
0148 O,
0149 indirect_result_t<F &, projected<I0, P0>, projected<I1, P1>>>)
0150 RANGES_DEPRECATED(
0151 "Use the variant of ranges::transform that takes an upper bound "
0152 "for both input ranges")
0153 binary_transform_result<I0, I1, O>
0154 RANGES_FUNC(transform)(I0 begin0,
0155 S0 end0,
0156 I1 begin1,
0157 O out,
0158 F fun,
0159 P0 proj0 = P0{},
0160 P1 proj1 = P1{})
0161 {
0162 return (*this)(std::move(begin0),
0163 std::move(end0),
0164 std::move(begin1),
0165 unreachable,
0166 std::move(out),
0167 std::move(fun),
0168 std::move(proj0),
0169 std::move(proj1));
0170 }
0171
0172
0173 template(typename Rng0,
0174 typename I1Ref,
0175 typename O,
0176 typename F,
0177 typename P0 = identity,
0178 typename P1 = identity)(
0179 requires input_range<Rng0> AND input_iterator<uncvref_t<I1Ref>> AND
0180 weakly_incrementable<O> AND copy_constructible<F> AND
0181 indirectly_writable<
0182 O,
0183 indirect_result_t<F &,
0184 projected<iterator_t<Rng0>, P0>,
0185 projected<uncvref_t<I1Ref>, P1>>>)
0186 RANGES_DEPRECATED(
0187 "Use the variant of ranges::transform that takes an upper bound "
0188 "for both input ranges")
0189 binary_transform_result<borrowed_iterator_t<Rng0>, uncvref_t<I1Ref>, O>
0190 RANGES_FUNC(transform)(Rng0 && rng0,
0191 I1Ref && begin1,
0192 O out,
0193 F fun,
0194 P0 proj0 = P0{},
0195 P1 proj1 = P1{})
0196 {
0197 return (*this)(begin(rng0),
0198 end(rng0),
0199 static_cast<I1Ref &&>(begin1),
0200 unreachable,
0201 std::move(out),
0202 std::move(fun),
0203 std::move(proj0),
0204 std::move(proj1));
0205 }
0206
0207 RANGES_FUNC_END(transform)
0208
0209 namespace cpp20
0210 {
0211 using ranges::binary_transform_result;
0212 using ranges::transform;
0213 using ranges::unary_transform_result;
0214 }
0215
0216 }
0217
0218 #include <range/v3/detail/epilogue.hpp>
0219
0220 #endif