Simple-Vector v1.3.0
Algorithm.hpp
Go to the documentation of this file.
1// Copyright Dominic Koepke 2021 - 2022.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at
4// https://www.boost.org/LICENSE_1_0.txt)
5
6#ifndef SIMPLE_VECTOR_ALGORITHM_HPP
7#define SIMPLE_VECTOR_ALGORITHM_HPP
8
9#pragma once
10
11#include "Concepts.hpp"
12
13#include <algorithm>
14#include <concepts>
15#include <execution>
16#include <ranges>
17
18namespace sl::vec
19{
39 template
40 <
41 std::ranges::input_range TRange,
42 std::weakly_incrementable TOut,
43 std::copy_constructible TUnaryOp
44 >
46 requires std::indirectly_writable
47 <
48 TOut,
49 std::indirect_result_t<TUnaryOp&, std::ranges::iterator_t<TRange>>
50 >
52 constexpr void transform_unseq(TRange&& range, TOut result, TUnaryOp unaryOp)
53 {
54 if (std::is_constant_evaluated())
55 {
56 std::ranges::transform(std::forward<TRange>(range), result, std::ref(unaryOp));
57 }
58 else // ReSharper disable once CppUnreachableCode
59 {
60 std::transform
61 (
62 std::execution::unseq,
63 std::ranges::cbegin(range),
64 std::ranges::cend(range),
65 result,
66 std::ref(unaryOp)
67 );
68 }
69 }
70
88 template
89 <
90 std::ranges::input_range TRange1,
91 std::ranges::input_range TRange2,
92 std::weakly_incrementable TOut,
93 std::copy_constructible TBinaryOp
94 >
96 requires std::indirectly_writable
97 <
98 TOut,
99 std::indirect_result_t<TBinaryOp&, std::ranges::iterator_t<TRange1>, std::ranges::iterator_t<TRange2>>
100 >
102 constexpr void transform_unseq
103 (
104 TRange1&& range1,
105 TRange2&& range2,
106 TOut result,
107 TBinaryOp binaryOp
108 )
109 {
110 if (std::is_constant_evaluated())
111 {
112 std::ranges::transform(std::forward<TRange1>(range1), std::forward<TRange2>(range2), result, std::ref(binaryOp));
113 }
114 else // ReSharper disable once CppUnreachableCode
115 {
116 std::transform
117 (
118 std::execution::unseq,
119 std::ranges::cbegin(range1),
120 std::ranges::cend(range1),
121 std::ranges::cbegin(range2),
122 result,
123 std::ref(binaryOp)
124 );
125 }
126 }
127
146 template
147 <
148 std::ranges::input_range TRange,
149 std::move_constructible T,
150 std::copy_constructible TBinaryOp,
151 std::copy_constructible TUnaryOp
152 >
154 requires std::indirectly_unary_invocable
155 <
156 TUnaryOp&,
157 std::ranges::iterator_t<TRange>
158 > &&
159 binary_invokable_with_all_overloads_implicit_convertible_to
160 <
161 TBinaryOp&,
162 T,
163 T,
164 std::indirect_result_t<TUnaryOp&, std::ranges::iterator_t<TRange>>
165 >
167 [[nodiscard]]
169 (
170 TRange&& range,
171 T init,
172 TBinaryOp binaryOp,
173 TUnaryOp unaryOp
174 )
175 {
176 if (std::is_constant_evaluated())
177 {
178 return std::transform_reduce
179 (
180 std::ranges::cbegin(range),
181 std::ranges::cend(range),
182 init,
183 std::ref(binaryOp),
184 std::ref(unaryOp)
185 );
186 }
187 // ReSharper disable once CppUnreachableCode
188 return std::transform_reduce
189 (
190 std::execution::unseq,
191 std::ranges::cbegin(range),
192 std::ranges::cend(range),
193 init,
194 std::ref(binaryOp),
195 std::ref(unaryOp)
196 );
197 }
198
219 template
220 <
221 std::ranges::input_range TRange1,
222 std::ranges::input_range TRange2,
223 std::move_constructible T,
224 std::copy_constructible TBinaryOp1,
225 std::copy_constructible TBinaryOp2
226 >
228 requires std::invocable
229 <
230 TBinaryOp2&,
231 std::iter_reference_t<std::ranges::iterator_t<TRange1>>,
232 std::iter_reference_t<std::ranges::iterator_t<TRange2>>
233 > &&
234 binary_invokable_with_all_overloads_implicit_convertible_to
235 <
236 TBinaryOp1&,
237 T,
238 T,
239 std::indirect_result_t<TBinaryOp2&, std::ranges::iterator_t<TRange1>, std::ranges::iterator_t<TRange2>>
240 >
242 [[nodiscard]]
244 (
245 TRange1&& range1,
246 TRange2&& range2,
247 T init,
248 TBinaryOp1 binaryOp1,
249 TBinaryOp2 binaryOp2
250 )
251 {
252 if (std::is_constant_evaluated())
253 {
254 return std::transform_reduce
255 (
256 std::ranges::cbegin(range1),
257 std::ranges::cend(range1),
258 std::ranges::cbegin(range2),
259 init,
260 std::ref(binaryOp1),
261 std::ref(binaryOp2)
262 );
263 }
264 // ReSharper disable once CppUnreachableCode
265 return std::transform_reduce
266 (
267 std::execution::unseq,
268 std::ranges::cbegin(range1),
269 std::ranges::cend(range1),
270 std::ranges::cbegin(range2),
271 init,
272 std::ref(binaryOp1),
273 std::ref(binaryOp2)
274 );
275 }
276
278}
279
280#endif
constexpr void transform_unseq(TRange &&range, TOut result, TUnaryOp unaryOp)
Applies the given unary operation to each element and writes into result.
Definition: Algorithm.hpp:52
constexpr T transform_reduce_unseq(TRange &&range, T init, TBinaryOp binaryOp, TUnaryOp unaryOp)
Applies the unaryOp to each elements from the range and reduces the results (possibly permuted and ag...
Definition: Algorithm.hpp:169
range(TRange &&) -> range< TRange >
Definition: Algorithm.hpp:19