7#include "../utility/utility.hpp"
8#include "../macros.hpp"
18hi_export_module(hikogui.algorithm.algorithm_misc);
20hi_export
namespace hi::inline
v1 {
27template<
typename T,
typename U,
typename F>
28inline T transform(
const U& input, F operation)
31 result.reserve(input.size());
41template<
typename T, std::
size_t N,
typename F>
47 a.
at(i) = operation(i);
65 hi_axiom(first != last);
69 auto new_last = last - 1;
70 swap(*element, *new_last);
74template<
typename It,
typename UnaryPredicate>
75constexpr It rfind_if(It
const first, It
const last, UnaryPredicate predicate)
87template<
typename It,
typename UnaryPredicate>
88constexpr It rfind_if_not(It
const first, It
const last, UnaryPredicate predicate)
90 return rfind_if(first, last, [&](
auto const& x) {
95template<
typename It,
typename T>
96constexpr It rfind(It
const first, It
const last, T
const& value)
98 return rfind_if(first, last, [&](
auto const& x) {
110template<
typename It,
typename ItAny>
111[[nodiscard]]
constexpr It
find_any(It data_first, It data_last, ItAny value_first, ItAny value_last)
noexcept
113 return std::find_if(data_first, data_last, [value_first, value_last](
auto const& data) {
114 return std::any_of(value_first, value_last, [&data](
auto const& value) {
115 return data == value;
126template<
typename ConstIt,
typename It,
typename UnaryPredicate>
127constexpr It
find_cluster(ConstIt last, It start, UnaryPredicate predicate)
129 auto const cluster_id = predicate(*start);
131 for (
auto i = start + 1; i != last; ++i) {
132 if (predicate(*i) != cluster_id) {
145template<
typename ConstIt,
typename It,
typename UnaryPredicate>
146constexpr It
rfind_cluster(ConstIt first, It start, UnaryPredicate predicate)
148 auto const cluster_id = predicate(*start);
150 if (start == first) {
156 if (predicate(*i) != cluster_id) {
175template<
typename ConstIt,
typename It,
typename UnaryPredicate>
186template<
typename It,
typename S,
typename F>
194 if (IsClusterSeperator(*first)) {
198 for (
auto i = first; i != last;) {
202 auto skipOverSeperator = (j == last) ? 0 : 1;
203 i = j + skipOverSeperator;
207template<
typename InputIt1,
typename InputIt2,
typename BinaryPredicate>
209rmismatch(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, BinaryPredicate predicate)
noexcept
215 if (i1 == first1 && i2 == first2) {
216 return {last1, last2};
217 }
else if (i1 == first1) {
218 return {last1, --i2};
219 }
else if (i2 == first2) {
220 return {--i1, last2};
223 if (!predicate(*(--i1), *(--i2))) {
229template<
typename InputIt1,
typename InputIt2>
232 return rmismatch(first1, last1, first2, last2, [&](
auto a,
auto b) {
238T smoothstep(T x)
noexcept
240 x = std::clamp(x, T{0.0}, T{1.0});
241 return x * x * (3 - 2 * x);
245T inverse_smoothstep(T x)
265auto shuffle_by_index(
auto first,
auto last,
auto indices_first,
auto indices_last,
auto index_op)
noexcept
273 src_indices.push_back(i);
277 for (
auto it = indices_first; it != indices_last; ++it, ++dst) {
278 auto const index = index_op(*it);
279 hi_assert_bounds(index, src_indices);
281 auto src = [&src_indices, index]() {
284 src = src_indices[src];
285 }
while (src_indices[src] != index);
291 std::iter_swap(begin(src_indices) + src, begin(src_indices) + dst);
311auto shuffle_by_index(
auto first,
auto last,
auto indices_first,
auto indices_last)
noexcept
313 return shuffle_by_index(first, last, indices_first, indices_last, [](
auto const& x) {
314 return narrow_cast<std::size_t>(x);
326template<
typename DataIt,
typename ValueIt>
327DataIt
front_strip(DataIt data_first, DataIt data_last, ValueIt value_first, ValueIt value_last)
noexcept
329 for (
auto it = data_first; it != data_last; ++it) {
330 if (
std::find(value_first, value_last, *it) == value_last) {
347template<
typename DataIt,
typename ValueIt>
348DataIt
back_strip(DataIt data_first, DataIt data_last, ValueIt value_first, ValueIt value_last)
noexcept
351 while (it != data_first) {
352 if (
std::find(value_first, value_last, *(--it)) == value_last) {
370template<std::endian Endian = std::endian::native,
typename T, std::
unsigned_
integral Key>
373 auto base = table.data();
374 auto len = table.size();
378 hi_axiom_not_null(base);
380 auto const half = len / 2;
382 if (load<Key, Endian>(base + half - 1) < key) {
387 if (load<Key, Endian>(base) < key) {
395template<std::endian Endian = std::endian::native,
typename T, std::
unsigned_
integral Key>
398 auto const ptr = fast_lower_bound<Endian>(table, key);
399 if (ptr ==
nullptr) {
403 if (load<Key, Endian>(ptr) != key) {
DOXYGEN BUG.
Definition algorithm_misc.hpp:20
constexpr It find_any(It data_first, It data_last, ItAny value_first, ItAny value_last) noexcept
Find the first occurrence of an value in a data.
Definition algorithm_misc.hpp:111
auto shuffle_by_index(auto first, auto last, auto indices_first, auto indices_last, auto index_op) noexcept
Shuffle a container based on a list of indices.
Definition algorithm_misc.hpp:265
DataIt front_strip(DataIt data_first, DataIt data_last, ValueIt value_first, ValueIt value_last) noexcept
Strip data from the front side.
Definition algorithm_misc.hpp:327
constexpr It unordered_remove(It first, It last, It element)
Remove element from a container.
Definition algorithm_misc.hpp:63
constexpr std::pair< It, It > bifind_cluster(ConstIt first, ConstIt last, It start, UnaryPredicate predicate)
Find the begin and end of the current cluster.
Definition algorithm_misc.hpp:176
constexpr T * fast_lower_bound(std::span< T > table, Key const &key) noexcept
The fast lower bound algorithm.
Definition algorithm_misc.hpp:371
constexpr It rfind_cluster(ConstIt first, It start, UnaryPredicate predicate)
Find the start of the current cluster.
Definition algorithm_misc.hpp:146
constexpr It find_cluster(ConstIt last, It start, UnaryPredicate predicate)
Find the start of the current cluster.
Definition algorithm_misc.hpp:127
DataIt back_strip(DataIt data_first, DataIt data_last, ValueIt value_first, ValueIt value_last) noexcept
Strip data from the back side.
Definition algorithm_misc.hpp:348
constexpr T * fast_binary_search_eq(std::span< T > table, Key const &key) noexcept
Search for the item that is equal to the key.
Definition algorithm_misc.hpp:396
constexpr std::array< T, N > generate_array(F operation)
Generate data in an array.
Definition algorithm_misc.hpp:42
void for_each_cluster(It first, It last, S IsClusterSeperator, F Function)
Definition algorithm_misc.hpp:187
T back_inserter(T... args)