Analytics Template Library
 All Classes Namespaces Functions Variables Pages
flat_set.hpp
1 
2 
3 #ifndef FLAT_SET_HPP
4 #define FLAT_SET_HPP
5 
6 
7 
8 #include <vector>
9 //#include "../AutoDiff/AlignedAllocator.hpp"
10 
11 
12 
13  template <typename ForwardIterator, typename T,class P>
14  inline ForwardIterator
15  fs_eastl_lower_bound(ForwardIterator first, ForwardIterator last, const T& value, P pred)
16  {
17  typedef typename std::iterator_traits<ForwardIterator>::difference_type DifferenceType;
18 
19  DifferenceType d = std::distance(first, last); // This will be efficient for a random access iterator such as an array.
20 
21  while(d > 0)
22  {
23  ForwardIterator i = first;
24  DifferenceType d2 = d >> 1; // We use '>>1' here instead of '/2' because MSVC++ for some reason generates significantly worse code for '/2'. Go figure.
25 
26  std::advance(i, d2); // This will be efficient for a random access iterator such as an array.
27 
28  if(pred(*i, value))
29  {
30  // Disabled because std::lower_bound doesn't specify (23.3.3.3, p3) this can be done: EASTL_VALIDATE_COMPARE(!(value < *i)); // Validate that the compare function is sane.
31  first = ++i;
32  d -= d2 + 1;
33  }
34  else
35  d = d2;
36  }
37  return first;
38  }
39 
40 template<class FwdIt, class T, class P>
41 inline FwdIt fs_branchless_lower_bound(FwdIt begin, FwdIt end, T const &val, P pred) {
42  while (begin != end) {
43  FwdIt middle(begin);
44  std::advance(middle, std::distance(begin, end) >> 1);
45  FwdIt middle_plus_one(middle);
46  ++middle_plus_one;
47  bool const b = pred(*middle, val);
48  begin = b ? middle_plus_one : begin;
49  end = b ? end : middle;
50  }
51  return begin;
52 }
53 
54 template <class T, class Compare = std::less<T>, class Allocator = std::allocator<T> >
55 class flat_set {
56  std::vector<T, Allocator> data_m;
57  Compare cmp;
58 public:
59  typedef typename std::vector<T>::iterator iterator;
60  typedef typename std::vector<T>::const_iterator const_iterator;
61  typedef typename std::vector<T>::reverse_iterator reverse_iterator;
62  typedef typename std::vector<T>::const_reverse_iterator const_reverse_iterator;
63 
64  flat_set(const Compare& c = Compare())
65  : data_m(), cmp(c) {
66 // data_m.reserve(8);
67  }
68 
69  template <class InputIterator>
70  flat_set(InputIterator first, InputIterator last,
71  const Compare& c = Compare())
72  : data_m(first, last), cmp(c) {
73  std::sort(begin(), end(), cmp);
74  }
75 
76  inline iterator erase(const T& t) {
77  iterator i = this->find(t);
78  if (i != this->end()) {
79  return data_m.erase(i);
80  } else {
81  return this->end();
82  }
83  }
84 
85  inline iterator insert(const T& t) {
86  iterator i = fs_eastl_lower_bound(begin(), end(), t, cmp);
87  if (i == end() || cmp(t, *i))
88  data_m.insert(i, std::move(t));
89  return i;
90  }
91 
92  inline void insert(const iterator& first, const iterator& last) {
93  iterator it;
94  for (it = first; it != last; ++it) {
95  this->insert((*it));
96  }
97 
98  }
99 
100  inline const_iterator find(const T& t) const {
101  const_iterator i = fs_eastl_lower_bound(begin(), end(), t, cmp);
102  return i == end() || cmp(t, *i) ? end() : i;
103  }
104 
105  inline iterator find(const T& t) {
106  iterator i =fs_eastl_lower_bound(begin(), end(), t, cmp);
107  return i == end() || cmp(t, *i) ? end() : i;
108  }
109 
110  inline iterator begin() {
111  return data_m.begin();
112  }
113 
114  inline iterator end() {
115  return data_m.end();
116  }
117 
118  inline const_iterator begin() const {
119  return data_m.begin();
120  }
121 
122  inline const_iterator end() const {
123  return data_m.end();
124  }
125 
126  inline reverse_iterator rbegin() {
127  return data_m.rbegin();
128  }
129 
130  inline reverse_iterator rend() {
131  return data_m.rend();
132  }
133 
134  inline const_reverse_iterator rbegin() const {
135  return data_m.rbegin();
136  }
137 
138  inline const_reverse_iterator rend() const {
139  return data_m.rend();
140  }
141 
142  inline size_t size() const {
143  return data_m.size();
144  }
145 
146  inline void reserve(size_t size) {
147  data_m.reserve(size);
148  }
149 
150  inline std::vector<T, Allocator>& data() {
151  return data_m;
152  }
153 
154  inline bool contains(const T& t) {
155  return std::binary_search(this->data_m.begin(), this->data_m.end(), t);
156  }
157 
158  inline void clear() {
159  data_m.clear();
160  }
161 
162  void clear_no_resize() {
163  data_m.resize(0);
164  }
165 
166 };
167 
168 template<typename T>
170  typedef std::vector<T> vector;
171 
172 public:
173  typedef typename vector::value_type value_type;
174  typedef typename vector::reference reference;
175  typedef typename vector::const_reference const_reference;
176  typedef typename vector::const_iterator iterator;
177  typedef typename vector::const_iterator const_iterator;
178  typedef typename vector::difference_type difference_type;
179  typedef typename vector::size_type size_type;
180 
182  }
183 
184  levelorder_vector(const levelorder_vector& x) : impl(x.impl) {
185  }
186 
187  levelorder_vector& operator=(const levelorder_vector& x) {
188  impl = x.impl;
189  return *this;
190  }
191 
192  template<typename InputIterator>
193  levelorder_vector(InputIterator first, InputIterator last) {
194  vector aux(first, last);
195  std::sort(aux.begin(), aux.end());
196  impl = aux;
197  insert(0, aux.size(), aux.begin());
198  }
199 
200  const_iterator begin()const {
201  return impl.begin();
202  }
203 
204  const_iterator end()const {
205  return impl.end();
206  }
207 
208  const_iterator cbegin()const {
209  return impl.cbegin();
210  }
211 
212  const_iterator cend()const {
213  return impl.cend();
214  }
215 
216  friend bool operator==(const levelorder_vector& x, const levelorder_vector& y) {
217  return x.impl == y.impl;
218  }
219 
220  friend bool operator!=(const levelorder_vector& x, const levelorder_vector& y) {
221  return x.impl != y.impl;
222  }
223 
224  void swap(levelorder_vector& x) {
225  impl.swap(x.impl);
226  }
227 
228  friend void swap(levelorder_vector& x, levelorder_vector& y) {
229  x.swap(y);
230  }
231 
232  size_type size()const {
233  return impl.size();
234  }
235 
236  size_type max_size()const {
237  return impl.max_size();
238  }
239 
240  bool empty()const {
241  return impl.empty();
242  }
243 
244  const_iterator lower_bound(const T& x)const {
245  size_type n = impl.size(), i = n, j = 0;
246  while (j < n) {
247  if (impl[j] < x) {
248  j = 2 * j + 2;
249  } else {
250  i = j;
251  j = 2 * j + 1;
252  }
253  }
254  return begin() + i;
255  }
256 
257  void build() {
258  std::sort(impl.begin(), impl.end());
259  // impl = aux_;
260  insert(0, impl.size(), impl.begin());
261  }
262 
263  void push(const T& t) {
264  impl.push_back(t);
265  }
266 
267  void clear() {
268  impl.clear();
269  }
270 
271  void clear_no_resize() {
272  impl.resize(0);
273  }
274 
275 private:
276 
277  void insert(size_type i, size_type n, const_iterator first) {
278  if (n) {
279  size_type h = root(n);
280  impl[i] = *(first + h);
281  insert(2 * i + 1, h, first);
282  insert(2 * i + 2, n - h - 1, first + h + 1);
283  }
284  }
285 
286  size_type root(size_type n) {
287  if (n <= 1)return 0;
288  size_type i = 2;
289  while (i <= n)i *= 2;
290  return std::min(i / 2 - 1, n - i / 4);
291  }
292 
293  vector impl;
294 
295 };
296 
297 
298 
299 #endif /* FLAT_SET_HPP */
300 
Definition: flat_set.hpp:55
Definition: flat_set.hpp:169