Analytics Template Library
 All Classes Namespaces Functions Variables Pages
flat_map.hpp
1 /*
2  * File: flat_map.hpp
3  * Author: matthewsupernaw
4  *
5  * Created on June 27, 2015, 3:21 PM
6  */
7 
8 #ifndef FLAT_MAP_HPP
9 #define FLAT_MAP_HPP
10 
11 #include <iostream>
12 #include <vector>
13 #include <list>
14 #include <algorithm>
15 #include <string>
16 #include <sstream>
17 #include <map>
18 #include <iterator>
19 
29 template <typename ForwardIterator, typename T, typename Compare >
30 inline ForwardIterator
31 eastl_lower_bound(ForwardIterator first, ForwardIterator last, const T& value, const Compare& compare) {
32  typedef typename std::iterator_traits<ForwardIterator>::difference_type DifferenceType;
33 
34  DifferenceType d = std::distance(first, last); // This will be efficient for a random access iterator such as an array.
35 
36  while (d > 0) {
37  ForwardIterator i = first;
38  DifferenceType d2 = d >> 1; // We use '>>1' here instead of '/2' because MSVC++ for some reason generates significantly worse code for '/2'. Go figure.
39 
40  std::advance(i, d2); // This will be efficient for a random access iterator such as an array.
41 
42  if (compare(*i, value)) {
43  // 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.
44  first = ++i;
45  d -= d2 + 1;
46  } else
47  d = d2;
48  }
49  return first;
50 }
51 
52 template<class FwdIt, class T, class P>
53 inline FwdIt branchless_lower_bound(FwdIt begin, FwdIt end, T const &val, P pred) {
54  while (begin != end) {
55  FwdIt middle(begin);
56  std::advance(middle, std::distance(begin, end) >> 1);
57  FwdIt middle_plus_one(middle);
58  ++middle_plus_one;
59  bool const b = pred(*middle, val);
60  begin = b ? middle_plus_one : begin;
61  end = b ? end : middle;
62  }
63  return begin;
64 }
65 
66 template<class Key, class T>
67 class flat_map {
68 public:
69 
70  typedef std::pair<Key, T> value_type;
71  typedef Key key_type;
72  typedef T mapped_type;
73 
74 private:
75  std::vector<value_type > data_m;
76 
77  struct compare_elems {
78 
79  inline const bool operator()(const value_type& x, const value_type& y) const {
80  return x.first < y.first;
81  }
82 
83  inline const bool operator()(const value_type& x, const key_type& y) const {
84  return x.first < y;
85  }
86 
87  inline const bool operator()(const key_type& x, const value_type& y) const {
88  return x < y.first;
89  }
90  };
91 
92 public:
93  typedef typename std::vector<value_type>::iterator iterator;
94  typedef typename std::vector<value_type>::const_iterator const_iterator;
95  typedef typename std::vector<value_type>::reverse_iterator reverse_iterator;
96  typedef typename std::vector<value_type>::const_reverse_iterator const_reverse_iterator;
97 
98  flat_map(std::size_t n = 0) {
99  data_m.reserve(n);
100  }
101 
102  inline std::pair<iterator, bool> insert(const value_type& value) {
103  iterator it = eastl_lower_bound(data_m.begin(), data_m.end(), value.first, compare_elems());
104  if (it == data_m.end() || it->first != value.first) {
105  iterator it2 = data_m.insert(it, value);
106  return std::make_pair(it2, true);
107  } else {
108  return std::make_pair(it, false);
109  }
110  }
111 
112  inline T& operator[](const Key& key) {
113  iterator it = eastl_lower_bound(data_m.begin(), data_m.end(), key, compare_elems());
114  if (it == data_m.end() || it->first != key) {
115  iterator it2 = data_m.insert(it, value_type(key, T()));
116  return it2->second;
117  } else {
118  return it->second;
119  }
120  }
121 
122  void swap(flat_map& m) {
123  data_m.swap(m.data_m);
124  }
125 
126  iterator find(const Key& key) {
127  iterator it = eastl_lower_bound(data_m.begin(), data_m.end(), key, compare_elems());
128  if (it == data_m.end() || it->first != key) {
129  return data_m.end();
130  } else {
131  return it;
132  }
133  }
134 
135  const_iterator find(const Key& key) const {
136  const_iterator it = eastl_lower_bound(data_m.begin(), data_m.end(), key, compare_elems());
137  if (it == data_m.end() || it->first != key) {
138  return data_m.end();
139  } else {
140  return it;
141  }
142  }
143 
144  void erase(const Key& key) {
145  iterator it = eastl_lower_bound(data_m.begin(), data_m.end(), key, compare_elems());
146  if (it != data_m.end() && it->first == key) {
147  data_m.erase(it);
148  }
149  }
150 
151  void clear() {
152  data_m.clear();
153  }
154 
155  void reset() {
156  data_m.resize(0);
157  }
158 
159  bool empty() const {
160  return data_m.empty();
161  }
162 
163  std::size_t size() const {
164  return data_m.size();
165  }
166 
167  iterator begin() {
168  return data_m.begin();
169  }
170 
171  iterator end() {
172  return data_m.end();
173  }
174 
175  const_iterator begin() const {
176  return data_m.begin();
177  }
178 
179  const_iterator end() const {
180  return data_m.end();
181  }
182 
183  reverse_iterator rbegin() {
184  return data_m.rbegin();
185  }
186 
187  reverse_iterator rend() {
188  return data_m.rend();
189  }
190 
191  const_reverse_iterator rbegin() const {
192  return data_m.rbegin();
193  }
194 
195  const_reverse_iterator rend() const {
196  return data_m.rend();
197  }
198 
199  std::vector<value_type >& data() {
200  return data_m;
201  }
202 
203  const std::vector<value_type >& data()const {
204  return data_m;
205  }
206 };
207 
208 
209 
210 #endif /* FLAT_MAP_HPP */
211 
Definition: flat_map.hpp:67