18#ifndef TRINITY_CONTAINERS_H
19#define TRINITY_CONTAINERS_H
57 throw std::out_of_range(
"index");
68 static_assert(std::is_base_of<std::forward_iterator_tag, typename std::iterator_traits<typename C::iterator>::iterator_category>::value,
"Invalid container passed to Trinity::Containers::RandomResize");
69 if (std::size(container) <= requestedSize)
71 auto keepIt = std::begin(container), curIt = std::begin(container);
72 uint32 elementsToKeep = requestedSize, elementsToProcess = std::size(container);
73 while (elementsToProcess)
76 if (
urand(1, elementsToProcess) <= elementsToKeep)
79 *keepIt = std::move(*curIt);
86 container.erase(keepIt, std::end(container));
89 template<
class C,
class Predicate>
90 void RandomResize(C& container, Predicate&& predicate, std::size_t requestedSize)
94 std::copy_if(std::begin(container), std::end(container), std::inserter(containerCopy, std::end(containerCopy)), predicate);
99 container = std::move(containerCopy);
110 auto it = std::begin(container);
111 std::advance(it,
urand(0,
uint32(std::size(container)) - 1));
127 auto it = std::begin(container);
128 std::advance(it,
urandweighted(weights.size(), weights.data()));
140 template<
class C,
class Fn>
143 std::vector<double> weights;
144 weights.reserve(std::size(container));
145 double weightSum = 0.0;
146 for (
auto& val : container)
148 double weight = weightExtractor(val);
149 weights.push_back(weight);
152 if (weightSum <= 0.0)
153 weights.assign(std::size(container), 1.0);
183 template<
class Iterator1,
class Iterator2>
184 bool Intersects(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2)
186 while (first1 != last1 && first2 != last2)
188 if (*first1 < *first2)
190 else if (*first2 < *first1)
201 template <
typename Container,
typename Predicate>
204 auto wpos = c.begin();
205 for (
auto rpos = c.begin(), end = c.end(); rpos != end; ++rpos)
210 std::ranges::swap(*rpos, *wpos);
214 c.erase(wpos, c.end());
217 template <
typename Container,
typename Predicate>
220 for (
auto it = c.begin(); it != c.end();)
230 template <
typename Container,
typename Predicate>
233 if constexpr (std::is_move_assignable_v<
decltype(*c.begin())>)
uint32 urandweighted(size_t count, double const *chances)
uint32 urand(uint32 min, uint32 max)
static RandomEngine & Instance()
CheckedBufferOutputIterator operator++(int)
CheckedBufferOutputIterator & operator++()
std::ptrdiff_t difference_type
std::output_iterator_tag iterator_category
CheckedBufferOutputIterator(T *buf, size_t n)
void EraseIfMoveAssignable(Container &c, Predicate p)
void EraseIfNotMoveAssignable(Container &c, Predicate p)
auto SelectRandomWeightedContainerElement(C const &container, std::vector< double > weights) -> decltype(std::begin(container))
void RandomShuffle(C &container)
Reorder the elements of the container randomly.
auto SelectRandomContainerElement(C const &container) -> typename std::add_const< decltype(*std::begin(container))>::type &
bool Intersects(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2)
void EraseIf(Container &c, Predicate p)
void RandomResize(C &container, std::size_t requestedSize)