7#include "utility/module.hpp"
13namespace hi::inline
v1 {
20template<
typename T,
typename U,
typename F>
21inline T transform(
const U& input, F operation)
24 result.reserve(input.size());
34template<
typename T, std::
size_t N,
typename F>
40 a.
at(i) = operation(i);
62 auto new_last = last - 1;
63 swap(*element, *new_last);
67template<
typename It,
typename UnaryPredicate>
68constexpr It rfind_if(It
const first, It
const last, UnaryPredicate predicate)
80template<
typename It,
typename UnaryPredicate>
81constexpr It rfind_if_not(It
const first, It
const last, UnaryPredicate predicate)
83 return rfind_if(first, last, [&](
hilet& x) {
88template<
typename It,
typename T>
89constexpr It rfind(It
const first, It
const last, T
const& value)
91 return rfind_if(first, last, [&](
hilet& x) {
103template<
typename It,
typename ItAny>
104[[nodiscard]]
constexpr It
find_any(It data_first, It data_last, ItAny value_first, ItAny value_last)
noexcept
106 return std::find_if(data_first, data_last, [value_first, value_last](
hilet& data) {
108 return data == value;
119template<
typename ConstIt,
typename It,
typename UnaryPredicate>
120constexpr It
find_cluster(ConstIt last, It start, UnaryPredicate predicate)
122 hilet cluster_id = predicate(*start);
124 for (
auto i = start + 1; i != last; ++i) {
125 if (predicate(*i) != cluster_id) {
138template<
typename ConstIt,
typename It,
typename UnaryPredicate>
139constexpr It
rfind_cluster(ConstIt first, It start, UnaryPredicate predicate)
141 hilet cluster_id = predicate(*start);
143 if (start == first) {
149 if (predicate(*i) != cluster_id) {
168template<
typename ConstIt,
typename It,
typename UnaryPredicate>
174template<
typename InputIt1,
typename InputIt2,
typename BinaryPredicate>
176rmismatch(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, BinaryPredicate predicate)
noexcept
182 if (i1 == first1 && i2 == first2) {
183 return {last1, last2};
184 }
else if (i1 == first1) {
185 return {last1, --i2};
186 }
else if (i2 == first2) {
187 return {--i1, last2};
190 if (!predicate(*(--i1), *(--i2))) {
196template<
typename InputIt1,
typename InputIt2>
199 return rmismatch(first1, last1, first2, last2, [&](
auto a,
auto b) {
205T smoothstep(T x)
noexcept
207 x = std::clamp(x, T{0.0}, T{1.0});
208 return x * x * (3 - 2 * x);
212T inverse_smoothstep(T x)
232auto shuffle_by_index(
auto first,
auto last,
auto indices_first,
auto indices_last,
auto index_op)
noexcept
240 src_indices.push_back(i);
244 for (
auto it = indices_first; it != indices_last; ++it, ++dst) {
245 hilet index = index_op(*it);
248 auto src = [&src_indices, index]() {
251 src = src_indices[src];
252 }
while (src_indices[src] != index);
258 std::iter_swap(begin(src_indices) + src, begin(src_indices) + dst);
278auto shuffle_by_index(
auto first,
auto last,
auto indices_first,
auto indices_last)
noexcept
281 return narrow_cast<std::size_t>(x);
293template<
typename DataIt,
typename ValueIt>
294DataIt
front_strip(DataIt data_first, DataIt data_last, ValueIt value_first, ValueIt value_last)
noexcept
296 for (
auto it = data_first; it != data_last; ++it) {
297 if (
std::find(value_first, value_last, *it) == value_last) {
314template<
typename DataIt,
typename ValueIt>
315DataIt
back_strip(DataIt data_first, DataIt data_last, ValueIt value_first, ValueIt value_last)
noexcept
318 while (it != data_first) {
319 if (
std::find(value_first, value_last, *(--it)) == value_last) {
337template<std::endian Endian = std::endian::native,
typename T, std::
unsigned_
integral Key>
340 auto base = table.data();
341 auto len = table.size();
347 hilet half = len / 2;
349 if (load<Key, Endian>(base + half - 1) < key) {
354 if (load<Key, Endian>(base) < key) {
362template<std::endian Endian = std::endian::native,
typename T, std::
unsigned_
integral Key>
365 hilet ptr = fast_lower_bound<Endian>(table, key);
366 if (ptr ==
nullptr) {
370 if (load<Key, Endian>(ptr) != key) {
#define hi_assert_bounds(x,...)
Assert if a value is within bounds.
Definition assert.hpp:225
#define hi_axiom(expression,...)
Specify an axiom; an expression that is true.
Definition assert.hpp:253
#define hi_axiom_not_null(expression,...)
Assert if an expression is not nullptr.
Definition assert.hpp:272
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
DOXYGEN BUG.
Definition algorithm.hpp:13
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.hpp:104
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.hpp:232
DataIt front_strip(DataIt data_first, DataIt data_last, ValueIt value_first, ValueIt value_last) noexcept
Strip data from the front side.
Definition algorithm.hpp:294
constexpr It unordered_remove(It first, It last, It element)
Remove element from a container.
Definition algorithm.hpp:56
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.hpp:169
constexpr T * fast_lower_bound(std::span< T > table, Key const &key) noexcept
The fast lower bound algorithm.
Definition algorithm.hpp:338
constexpr It rfind_cluster(ConstIt first, It start, UnaryPredicate predicate)
Find the start of the current cluster.
Definition algorithm.hpp:139
constexpr It find_cluster(ConstIt last, It start, UnaryPredicate predicate)
Find the start of the current cluster.
Definition algorithm.hpp:120
DataIt back_strip(DataIt data_first, DataIt data_last, ValueIt value_first, ValueIt value_last) noexcept
Strip data from the back side.
Definition algorithm.hpp:315
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.hpp:363
constexpr std::array< T, N > generate_array(F operation)
Generate data in an array.
Definition algorithm.hpp:35
T back_inserter(T... args)