6#include "TTauri/Foundation/required.hpp"
18template<
typename T,
typename U,
typename F>
19inline T
transform(
const U &input, F operation)
22 result.reserve(input.size());
32template<
typename T,
size_t N,
typename F>
37 for (
size_t i = 0; i < N; i++) {
38 a.
at(i) = operation(i);
48template<
typename T,
typename F>
49inline void erase_if(T &v, F predicate)
61template<
typename It,
typename UnaryPredicate>
62constexpr It rfind_if(It
const first, It
const last, UnaryPredicate predicate)
74template<
typename It,
typename UnaryPredicate>
75constexpr It rfind_if_not(It
const first, It
const last, UnaryPredicate predicate)
77 return rfind_if(first, last, [&](ttlet &x) {
return !predicate(x); });
80template<
typename It,
typename T>
81constexpr It rfind(It
const first, It
const last, T
const &value)
83 return rfind_if(first, last, [&](ttlet &x) {
return x == value; });
92template<
typename ConstIt,
typename It,
typename UnaryPredicate>
93constexpr It find_cluster(ConstIt last, It start, UnaryPredicate predicate)
95 ttlet cluster_id = predicate(*start);
97 for (
auto i = start + 1; i != last; ++i) {
98 if (predicate(*i) != cluster_id) {
111template<
typename ConstIt,
typename It,
typename UnaryPredicate>
112constexpr It rfind_cluster(ConstIt first, It start, UnaryPredicate predicate)
114 ttlet cluster_id = predicate(*start);
116 if (start == first) {
122 if (predicate(*i) != cluster_id) {
141template<
typename ConstIt,
typename It,
typename UnaryPredicate>
142constexpr std::pair<It,It> bifind_cluster(ConstIt first, ConstIt last, It start, UnaryPredicate predicate)
145 rfind_cluster(first, start, predicate),
146 find_cluster(last, start, predicate)
155template<
typename It,
typename S,
typename F>
156inline void for_each_cluster(It first, It last, S IsClusterSeperator, F Function)
163 if (IsClusterSeperator(*first)) {
167 for (
auto i = first; i != last;) {
171 auto skipOverSeperator = (j == last) ? 0 : 1;
172 i = j + skipOverSeperator;
176template<
typename InputIt1,
typename InputIt2>
177inline bool starts_with(InputIt1 haystack_first, InputIt1 haystack_last, InputIt2 needle_first, InputIt2 needle_last)
noexcept
179 ttlet [haystack_result, needle_result] =
std::mismatch(haystack_first, haystack_last, needle_first, needle_last);
180 return needle_result == needle_last;
183template<
typename Container1,
typename Container2>
184inline bool starts_with(Container1 haystack, Container2 needle)
noexcept
186 return starts_with(haystack.begin(), haystack.end(), needle.begin(), needle.end());
189template<
typename InputIt1,
typename InputIt2,
typename BinaryPredicate>
190inline std::pair<InputIt1,InputIt2> rmismatch(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, BinaryPredicate predicate)
noexcept
196 if (i1 == first1 && i2 == first2) {
197 return {last1, last2};
198 }
else if (i1 == first1) {
199 return {last1, --i2};
200 }
else if (i2 == first2) {
201 return {--i1, last2};
204 if (!predicate(*(--i1), *(--i2))) {
210template<
typename InputIt1,
typename InputIt2>
213 return rmismatch(first1, last1, first2, last2, [&](
auto a,
auto b) {
return a == b; });
216template<
typename InputIt1,
typename InputIt2>
217inline bool ends_with(InputIt1 haystack_first, InputIt1 haystack_last, InputIt2 needle_first, InputIt2 needle_last)
noexcept
219 ttlet [haystack_result, needle_result] = rmismatch(haystack_first, haystack_last, needle_first, needle_last);
220 return needle_result == needle_last;
223template<
typename Container1,
typename Container2>
224inline bool ends_with(Container1 haystack, Container2 needle)
noexcept
226 return ends_with(haystack.begin(), haystack.end(), needle.begin(), needle.end());
230T smoothstep(T x)
noexcept {
231 x = std::clamp(x, T{0.0}, T{1.0});
232 return x * x * (3 - 2 * x);
236T inverse_smoothstep(T x) {
245template<
typename T,
typename MixType, std::enable_if_t<std::is_
floating_po
int_v<MixType>,
int> = 0>
246T mix(MixType mix_value, T
const &lhs, T
const &rhs)
noexcept
248 if (mix_value >= MixType(1.0)) {
250 }
else if (mix_value <= MixType(0.0)) {
253 return lhs + (rhs - lhs) * mix_value;
T back_inserter(T... args)