18#ifndef TRINITY_CONTAINERS_H
19#define TRINITY_CONTAINERS_H
58 throw std::out_of_range(
"index");
69 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");
70 if (
std::size(container) <= requestedSize)
72 auto keepIt = std::begin(container), curIt = std::begin(container);
73 uint32 elementsToKeep = requestedSize, elementsToProcess =
std::size(container);
74 while (elementsToProcess)
77 if (
urand(1, elementsToProcess) <= elementsToKeep)
80 *keepIt = std::move(*curIt);
87 container.erase(keepIt, std::end(container));
90 template<
class C,
class Predicate>
91 void RandomResize(C& container, Predicate&& predicate, std::size_t requestedSize)
95 std::copy_if(std::begin(container), std::end(container), std::inserter(containerCopy, std::end(containerCopy)), predicate);
100 container = std::move(containerCopy);
111 auto it = std::begin(container);
128 auto it = std::begin(container);
129 std::advance(it,
urandweighted(weights.size(), weights.data()));
141 template<
class C,
class Fn>
146 double* weights =
new double[
size];
147 double weightSum = 0.0;
148 for (
auto const& val : container)
150 double weight = weightExtractor(val);
151 weights[i++] = weight;
155 auto it = std::begin(container);
169 template<
class Iterator>
200 template<
class Iterator1,
class Iterator2>
201 inline bool Intersects(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2)
203 while (first1 != last1 && first2 != last2)
205 if (*first1 < *first2)
207 else if (*first2 < *first1)
229 template<
class Iterator1,
class Iterator2,
class Predicate>
230 inline bool Intersects(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, Predicate&& equalPred)
232 while (first1 != last1 && first2 != last2)
234 if (*first1 < *first2)
236 else if (*first2 < *first1)
238 else if (!equalPred(*first1, *first2))
249 template <
typename Container,
typename Predicate>
252 auto wpos = c.begin();
253 for (
auto rpos = c.begin(), end = c.end(); rpos != end; ++rpos)
258 std::swap(*rpos, *wpos);
262 c.erase(wpos, c.end());
265 template <
typename Container,
typename Predicate>
268 for (
auto it = c.begin(); it != c.end();)
278 template <
typename Container,
typename Predicate>
281 if constexpr (std::is_move_assignable_v<
decltype(*c.begin())>)
313 vec.resize(i + 1, resizeDefault);
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)
decltype(auto) EnsureWritableVectorIndex(std::vector< T > &vec, typename std::vector< T >::size_type i)
void RandomShuffle(Iterator begin, Iterator end)
Reorder the elements of the iterator range randomly.
auto SelectRandomWeightedContainerElement(C const &container, std::span< double > const &weights) -> decltype(std::begin(container))
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)
constexpr std::size_t size()