6 #ifndef SWIFT_MISC_ALGORITHM_H
7 #define SWIFT_MISC_ALGORITHM_H
24 template <
typename I,
typename J>
28 std::for_each(begin2, end2, [&](
const auto &rm) {
29 const auto found = std::find(begin1, end1, rm);
30 Q_ASSERT(found != end1);
31 if (newEnd == end1) { newEnd = found; }
32 else { newEnd = std::move(begin1, found, newEnd); }
33 begin1 = std::next(found);
35 if (newEnd != end1) { newEnd = std::move(begin1, end1, newEnd); }
43 inline std::mt19937 &defaultRandomGenerator()
45 thread_local std::mt19937 rng(std::random_device {}());
53 template <
typename ForwardIt,
typename OutputIt,
typename Generator>
56 for (
auto size =
static_cast<int>(std::distance(in,
end)); in !=
end && n > 0; ++in, --size)
58 if (std::uniform_int_distribution<>(0, size - 1)(rng) < n)
69 template <
typename ForwardIt,
typename OutputIt>
79 template <
typename ForwardIt,
typename OutputIt,
typename Generator>
82 const auto size =
static_cast<int>(std::distance(in,
end));
83 for (
int i = 0; i < std::min(n, size); ++i)
85 const auto index = std::uniform_int_distribution<>(0, std::max(size / n, 1) - 1)(rng);
86 std::advance(in, index);
88 std::advance(in, std::max(size / n, 1) - index);
95 template <
typename ForwardIt,
typename OutputIt>
113 template <
typename I,
typename F>
116 using value_type =
typename std::iterator_traits<I>::value_type;
120 auto newPart = std::partition(part,
end, [=](
const value_type &a) {
121 return std::none_of(part,
end, [=, &a](
const value_type &b) {
return comparator(b, a); });
123 Q_ASSERT_X(newPart != part,
"swift::misc::topologicalSort",
124 "Cyclic less-than relation detected (not a partial ordering)");
141 template <
typename C,
typename T,
typename F>
144 using value_type =
typename C::value_type;
145 using reverse = std::reverse_iterator<typename C::iterator>;
146 auto rit = std::find_if(reverse(container.end()), reverse(container.begin()),
147 [=, &value](
const value_type &lhs) { return comparator(lhs, value); });
148 Q_ASSERT_X(std::none_of(rit, reverse(container.begin()),
149 [=, &value](
const value_type &rhs) { return comparator(value, rhs); }),
150 "swift::misc::topologicallySortedInsert",
151 "Cyclic less-than relation detected (not a partial ordering)");
152 container.insert(rit.base(), std::forward<T>(value));
158 template <
typename T,
typename F,
size_t... Is>
159 void tupleForEachPairImpl(T &&tuple, F &&visitor, std::index_sequence<Is...>)
162 (
static_cast<void>(std::forward<F>(visitor)(std::get<Is * 2>(std::forward<T>(tuple)),
163 std::get<Is * 2 + 1>(std::forward<T>(tuple)))),
171 template <
typename T,
typename F>
174 using seq = std::make_index_sequence<std::tuple_size_v<std::decay_t<T>> / 2>;
175 return private_ns::tupleForEachPairImpl(std::forward<T>(tuple), std::forward<F>(visitor), seq());
Free functions in swift::misc.
T::const_iterator begin(const LockFreeReader< T > &reader)
Non-member begin() and end() for so LockFree containers can be used in ranged for loops.
void topologicalSort(I begin, I end, F comparator)
Topological sorting algorithm.
auto removeIfIn(I begin1, I end1, J begin2, J end2)
Removes those elements in range 1 that appear also in range 2 leaving only those that do not appear i...
void tupleForEachPair(T &&tuple, F &&visitor)
Invoke a visitor function on each pair of elements of a tuple in order.
T::const_iterator end(const LockFreeReader< T > &reader)
Non-member begin() and end() for so LockFree containers can be used in ranged for loops.
void copySampleElements(ForwardIt in, ForwardIt end, OutputIt out, int n, Generator &&rng)
Split the range [in,end) into n equal chunks and use the random number generator rng to choose one el...
void topologicallySortedInsert(C &container, T &&value, F comparator)
Insert an element into a sequential container while preserving the topological ordering of the contai...
void copyRandomElements(ForwardIt in, ForwardIt end, OutputIt out, int n, Generator &&rng)
Use the random number generator rng to choose n elements from the range [in,end) and copy them to out...