TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Containers.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the
6  * Free Software Foundation; either version 2 of the License, or (at your
7  * option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef TRINITY_CONTAINERS_H
19 #define TRINITY_CONTAINERS_H
20 
21 #include "Define.h"
22 #include "Random.h"
23 #include "Util.h"
24 #include <algorithm>
25 #include <functional>
26 #include <list>
27 #include <vector>
28 
29 namespace Trinity
30 {
31  namespace Containers
32  {
33  template<class T>
34  void RandomResizeList(std::list<T> &list, uint32 size)
35  {
36  uint32 list_size = uint32(list.size());
37 
38  while (list_size > size)
39  {
40  typename std::list<T>::iterator itr = list.begin();
41  std::advance(itr, urand(0, list_size - 1));
42  list.erase(itr);
43  --list_size;
44  }
45  }
46 
47  template<class T, class Predicate>
48  void RandomResizeList(std::list<T> &list, Predicate& predicate, uint32 size)
49  {
51  std::list<T> listCopy;
52  for (typename std::list<T>::iterator itr = list.begin(); itr != list.end(); ++itr)
53  if (predicate(*itr))
54  listCopy.push_back(*itr);
55 
56  if (size)
57  RandomResizeList(listCopy, size);
58 
59  list = listCopy;
60  }
61 
62  /*
63  * Select a random element from a container.
64  *
65  * Note: container cannot be empty
66  */
67  template <class C>
68  typename C::value_type const& SelectRandomContainerElement(C const& container)
69  {
70  typename C::const_iterator it = container.begin();
71  std::advance(it, urand(0, uint32(container.size()) - 1));
72  return *it;
73  }
74 
75  /*
76  * Select a random element from a container where each element has a different chance to be selected.
77  *
78  * @param container Container to select an element from
79  * @param weights Chances of each element to be selected, must be in the same order as elements in container.
80  * Caller is responsible for checking that sum of all weights is greater than 0.
81  *
82  * Note: container cannot be empty
83  */
84  template <class C>
85  typename C::const_iterator SelectRandomWeightedContainerElement(C const& container, std::vector<double> weights)
86  {
87  Trinity::discrete_distribution_param<uint32> ddParam(weights.begin(), weights.end());
88  std::discrete_distribution<uint32> dd(ddParam);
89  typename C::const_iterator it = container.begin();
91  return it;
92  }
93 
94  /*
95  * Select a random element from a container where each element has a different chance to be selected.
96  *
97  * @param container Container to select an element from
98  * @param weightExtractor Function retrieving chance of each element in container, expected to take an element of the container and returning a double
99  *
100  * Note: container cannot be empty
101  */
102  template <class C, class Fn>
103  typename C::const_iterator SelectRandomWeightedContainerElement(C const& container, Fn weightExtractor)
104  {
105  std::vector<double> weights;
106  weights.reserve(container.size());
107  double weightSum = 0.0;
108  for (auto itr = container.begin(); itr != container.end(); ++itr)
109  {
110  double weight = weightExtractor(*itr);
111  weights.push_back(weight);
112  weightSum += weight;
113  }
114  if (weightSum <= 0.0)
115  weights.assign(container.size(), 1.0);
116 
117  return SelectRandomWeightedContainerElement(container, weights);
118  }
119 
132  template<class Iterator1, class Iterator2>
133  bool Intersects(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2)
134  {
135  while (first1 != last1 && first2 != last2)
136  {
137  if (*first1 < *first2)
138  ++first1;
139  else if (*first2 < *first1)
140  ++first2;
141  else
142  return true;
143  }
144 
145  return false;
146  }
147 
148  template<class K, class V, template<class, class, class...> class M, class... Rest>
149  void MultimapErasePair(M<K, V, Rest...>& multimap, K const& key, V const& value)
150  {
151  auto range = multimap.equal_range(key);
152  for (auto itr = range.first; itr != range.second;)
153  {
154  if (itr->second == value)
155  itr = multimap.erase(itr);
156  else
157  ++itr;
158  }
159  }
160  }
162 }
164 
165 #endif
C::value_type const & SelectRandomContainerElement(C const &container)
Definition: Containers.h:68
C::const_iterator SelectRandomWeightedContainerElement(C const &container, std::vector< double > weights)
Definition: Containers.h:85
void RandomResizeList(std::list< T > &list, uint32 size)
Definition: Containers.h:34
void advance(octet_iterator &it, distance_type n, octet_iterator end)
Definition: checked.h:190
static SFMTEngine & Instance()
Definition: Random.cpp:79
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:45
uint32_t uint32
Definition: Define.h:150
bool Intersects(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2)
Definition: Containers.h:133
void MultimapErasePair(M< K, V, Rest...> &multimap, K const &key, V const &value)
Definition: Containers.h:149
const FieldDescriptor value
Definition: descriptor.h:1522
uint32_t uint32
Definition: g3dmath.h:168
Definition: Common.h:172