22template<
typename T,
typename U,
typename F>
23inline T
transform(
const U &input, F operation)
26 result.reserve(input.size());
36template<
typename T,
size_t N,
typename F>
41 for (
size_t i = 0; i < N; i++) {
42 a.
at(i) = operation(i);
52template<
typename T,
typename F>
53inline void erase_if(T &v, F predicate)
64template<
typename It,
typename UnaryPredicate>
65constexpr It rfind_if(It
const first, It
const last, UnaryPredicate predicate)
77template<
typename It,
typename UnaryPredicate>
78constexpr It rfind_if_not(It
const first, It
const last, UnaryPredicate predicate)
80 return rfind_if(first, last, [&](ttlet &x) {
85template<
typename It,
typename T>
86constexpr It rfind(It
const first, It
const last, T
const &value)
88 return rfind_if(first, last, [&](ttlet &x) {
100template<
typename It,
typename ItAny>
101[[nodiscard]]
constexpr It find_any(It data_first, It data_last, ItAny value_first, ItAny value_last)
noexcept
103 return std::find_if(data_first, data_last, [value_first, value_last](ttlet &data) {
104 return std::any_of(value_first, value_last, [&data](ttlet &value) {
105 return data == value;
116template<
typename ConstIt,
typename It,
typename UnaryPredicate>
117constexpr It find_cluster(ConstIt last, It start, UnaryPredicate predicate)
119 ttlet cluster_id = predicate(*start);
121 for (
auto i = start + 1; i != last; ++i) {
122 if (predicate(*i) != cluster_id) {
135template<
typename ConstIt,
typename It,
typename UnaryPredicate>
136constexpr It rfind_cluster(ConstIt first, It start, UnaryPredicate predicate)
138 ttlet cluster_id = predicate(*start);
140 if (start == first) {
146 if (predicate(*i) != cluster_id) {
165template<
typename ConstIt,
typename It,
typename UnaryPredicate>
166constexpr std::pair<It, It> bifind_cluster(ConstIt first, ConstIt last, It start, UnaryPredicate predicate)
168 return {rfind_cluster(first, start, predicate), find_cluster(last, start, predicate)};
176template<
typename It,
typename S,
typename F>
177inline void for_each_cluster(It first, It last, S IsClusterSeperator, F Function)
184 if (IsClusterSeperator(*first)) {
188 for (
auto i = first; i != last;) {
192 auto skipOverSeperator = (j == last) ? 0 : 1;
193 i = j + skipOverSeperator;
197template<
typename InputIt1,
typename InputIt2,
typename BinaryPredicate>
199rmismatch(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, BinaryPredicate predicate)
noexcept
205 if (i1 == first1 && i2 == first2) {
206 return {last1, last2};
207 }
else if (i1 == first1) {
208 return {last1, --i2};
209 }
else if (i2 == first2) {
210 return {--i1, last2};
213 if (!predicate(*(--i1), *(--i2))) {
219template<
typename InputIt1,
typename InputIt2>
222 return rmismatch(first1, last1, first2, last2, [&](
auto a,
auto b) {
228T smoothstep(T x)
noexcept
230 x = std::clamp(x, T{0.0}, T{1.0});
231 return x * x * (3 - 2 * x);
235T 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;
272auto shuffle_by_index(
auto first,
auto last,
auto indices_first,
auto indices_last,
auto index_op)
noexcept
279 for (
size_t i = 0; i != size; ++i) {
280 src_indices.push_back(i);
284 for (
auto it = indices_first; it != indices_last; ++it, ++dst) {
285 ttlet index = index_op(*it);
286 tt_axiom(index < std::size(src_indices));
288 auto src = [&src_indices,index]() {
291 src = src_indices[src];
292 }
while (src_indices[src] != index);
318auto shuffle_by_index(
auto first,
auto last,
auto indices_first,
auto indices_last)
noexcept
320 return shuffle_by_index(first, last, indices_first, indices_last, [](ttlet &x) {
321 return narrow_cast<size_t>(x);
333template<
typename DataIt,
typename ValueIt>
334DataIt front_strip(DataIt data_first, DataIt data_last, ValueIt value_first, ValueIt value_last)
noexcept
336 for (
auto it = data_first; it != data_last; ++it) {
338 if (!
std::any_of(value_first, value_last, [&data](ttlet &value) {
339 return data == value;
356template<
typename DataIt,
typename ValueIt>
357DataIt back_strip(DataIt data_first, DataIt data_last, ValueIt value_first, ValueIt value_last)
noexcept
359 for (
auto it = data_last - 1; it >= data_first; ++it) {
361 if (!
std::any_of(value_first, value_last, [&data](ttlet &value) {
362 return data == value;
T back_inserter(T... args)