CeresEngine 0.2.0
A game development framework
Loading...
Searching...
No Matches
UnaryAlgorithm.hpp
Go to the documentation of this file.
1//
2// CeresEngine - A game development framework
3//
4// Created by Rogiel Sulzbach.
5// Copyright (c) 2018-2022 Rogiel Sulzbach. All rights reserved.
6//
7
8#pragma once
9
19
20#include "Partitioner.hpp"
21
25
26namespace CeresEngine {
27
34 template<class Derived> class UnaryAlgorithmFunctor {
35 public:
36 template<class E, class P, class I, class S, class Fun>
37 requires(
38 // clang-format off
39 traits::is_executor_v<E> &&
40 traits::is_partitioner_v<P, I, S> &&
41 traits::is_input_iterator_v<I> &&
42 traits::is_sentinel_for_v<S, I> &&
43 traits::is_indirectly_unary_invocable_v<Fun, I> &&
44 std::is_copy_constructible_v<Fun>
45 // clang-format on
46 ) constexpr decltype(auto)
47 operator()(const E& executor, P p, I first, S last, Fun f) const {
48 if(std::is_constant_evaluated()) {
49 return Derived().run(make_inline_executor(), HalvePartitioner(1), first, last, std::move(f));
50 } else {
51 return Derived().run(executor, p, first, last, std::move(f));
52 }
53 }
54
56 template<class E, class P, class R, class Fun>
57 requires(
58 // clang-format off
59 traits::is_executor_v<E> &&
60 traits::is_range_partitioner_v<P, R> &&
61 traits::is_input_range_v<R> &&
62 traits::is_indirectly_unary_invocable_v<Fun, traits::iterator_t<R>> &&
63 std::is_copy_constructible_v<Fun>
64 // clang-format on
65 ) constexpr decltype(auto)
66 operator()(const E& executor, P p, R&& r, Fun f) const {
67 if(std::is_constant_evaluated()) {
68 return operator()(make_inline_executor(), HalvePartitioner(1), std::begin(r), std::end(r), std::move(f));
69 } else {
70 return operator()(executor, p, std::begin(r), std::end(r), std::move(f));
71 }
72 }
73
75 template<class P, class I, class S, class Fun>
76 requires(
77 // clang-format off
78 traits::is_partitioner_v<P, I,S> &&
79 traits::is_input_iterator_v<I> &&
80 traits::is_sentinel_for_v<S, I> &&
81 traits::is_indirectly_unary_invocable_v<Fun, I> &&
82 std::is_copy_constructible_v<Fun>
83 // clang-format off
84 )
85 constexpr decltype(auto)
86 operator()(P p, I first, S last, Fun f) const {
87 if (std::is_constant_evaluated()) {
88 return Derived().run(
91 first,
92 last,
93 std::move(f));
94 } else {
95 return Derived().run(
97 p,
98 first,
99 last,
100 std::move(f));
101 }
102 }
103
105 template <
106 class P,
107 class R,
108 class Fun> requires(
109 // clang-format off
110 traits::is_range_partitioner_v<P,R> &&
111 traits::is_input_range_v<R> &&
112 traits::is_indirectly_unary_invocable_v<Fun, traits::iterator_t<R>> &&
113 std::is_copy_constructible_v<Fun>
114 // clang-format on
115 ) constexpr decltype(auto)
116 operator()(P p, R&& r, Fun f) const {
117 if(std::is_constant_evaluated()) {
118 return operator()(make_inline_executor(), HalvePartitioner(1), std::begin(r), std::end(r), std::move(f));
119 } else {
120 return operator()(make_default_executor(), p, std::begin(r), std::end(r), std::move(f));
121 }
122 }
123
125 template<class E, class I, class S, class Fun>
126 requires(
127 // clang-format off
128 traits::is_executor_v<E> &&
129 traits::is_input_iterator_v<I> &&
130 traits::is_sentinel_for_v<S, I> &&
131 traits::is_indirectly_unary_invocable_v<Fun, I> &&
132 std::is_copy_constructible_v<Fun>
133 // clang-format on
134 ) constexpr decltype(auto)
135 operator()(const E& executor, I first, S last, Fun f) const {
136 if(std::is_constant_evaluated()) {
137 return operator()(make_inline_executor(), HalvePartitioner(1), first, last, std::move(f));
138 } else {
139 return operator()(executor, make_default_partitioner(executor, first, last), first, last, std::move(f));
140 }
141 }
142
144 template<class E, class R, class Fun>
145 requires(
146 // clang-format off
147 traits::is_executor_v<E> &&
148 traits::is_input_range_v<R> &&
149 traits::is_indirectly_unary_invocable_v<Fun, traits::iterator_t<R>> &&
150 std::is_copy_constructible_v<Fun>
151 // clang-format on
152 ) constexpr decltype(auto)
153 operator()(const E& executor, R&& r, Fun f) const {
154 if(std::is_constant_evaluated()) {
155 return operator()(make_inline_executor(), HalvePartitioner(1), std::begin(r), std::end(r), std::move(f));
156 } else {
157 return operator()(executor, make_default_partitioner(executor, std::forward<R>(r)), std::begin(r), std::end(r), std::move(f));
158 }
159 }
160
162 template<class I, class S, class Fun>
163 requires(
164 // clang-format off
165 traits::is_input_iterator_v<I> &&
166 traits::is_sentinel_for_v<S, I> &&
167 traits::is_indirectly_unary_invocable_v<Fun, I> &&
168 std::is_copy_constructible_v<Fun>
169 // clang-format on
170 ) constexpr decltype(auto)
171 operator()(I first, S last, Fun f) const {
172 if(std::is_constant_evaluated()) {
173 return operator()(make_inline_executor(), HalvePartitioner(1), first, last, std::move(f));
174 } else {
175 return operator()(make_default_executor(), make_default_partitioner(first, last), first, last, std::move(f));
176 }
177 }
178
180 template<class R, class Fun>
181 requires(
182 // clang-format off
183 traits::is_input_range_v<R> &&
184 traits::is_indirectly_unary_invocable_v<Fun, traits::iterator_t<R>> &&
185 std::is_copy_constructible_v<Fun>
186 // clang-format on
187 ) constexpr decltype(auto)
188 operator()(R&& r, Fun f) const {
189 if(std::is_constant_evaluated()) {
190 return operator()(make_inline_executor(), HalvePartitioner(make_grain_size(r.size())), std::begin(r), std::end(r), std::move(f));
191 } else {
192 return operator()(make_default_executor(), make_default_partitioner(r), std::begin(r), std::end(r), std::move(f));
193 }
194 }
195 };
196
197} // namespace CeresEngine
A partitioner is a light callable object that takes a pair of iterators and returns the middle of the...
The halve partitioner always splits the sequence into two parts of roughly equal size.
Definition Partitioner.hpp:37
Overloads for unary invoke algorithms.
Definition UnaryAlgorithm.hpp:34
constexpr decltype(auto) operator()(const E &executor, P p, R &&r, Fun f) const
Overload for Ranges.
Definition UnaryAlgorithm.hpp:66
constexpr decltype(auto) operator()(const E &executor, I first, S last, Fun f) const
Overload for Iterators / default partitioner.
Definition UnaryAlgorithm.hpp:135
constexpr decltype(auto) operator()(P p, I first, S last, Fun f) const
Overload for Iterators / default parallel executor.
Definition UnaryAlgorithm.hpp:86
constexpr decltype(auto) operator()(I first, S last, Fun f) const
Overload for Iterators / default executor / default partitioner.
Definition UnaryAlgorithm.hpp:171
constexpr decltype(auto) operator()(R &&r, Fun f) const
Overload for Ranges / default executor / default partitioner.
Definition UnaryAlgorithm.hpp:188
constexpr decltype(auto) operator()(const E &executor, P p, I first, S last, Fun f) const
Definition UnaryAlgorithm.hpp:47
constexpr decltype(auto) operator()(const E &executor, R &&r, Fun f) const
Overload for Ranges / default partitioner.
Definition UnaryAlgorithm.hpp:153
Definition Application.hpp:19
constexpr auto make_inline_executor()
An executor that runs anything inline.
Definition ExecutionContext.hpp:660
constexpr std::size_t make_grain_size(const std::size_t n, const std::size_t occupancy=hardware_concurrency())
Determine a reasonable minimum grain size depending on the number of elements in a sequence.
Definition Partitioner.hpp:89
auto make_default_executor()
The default executor to be used when no other executor is provided.
Definition ExecutionContext.hpp:743
constexpr size_t hash(const T &v)
Generates a hash for the provided type.
Definition Hash.hpp:25
DefaultPartitioner make_default_partitioner(const size_t n, const std::size_t occupancy=hardware_concurrency())
Create an instance of the default partitioner with a reasonable grain size for n elements.
Definition Partitioner.hpp:97