00001
00024 #ifndef GALOIS_FLATMAP_H
00025 #define GALOIS_FLATMAP_H
00026
00027 #include "Galois/config.h"
00028
00029 #include GALOIS_CXX11_STD_HEADER(functional)
00030 #include GALOIS_CXX11_STD_HEADER(algorithm)
00031 #include GALOIS_CXX11_STD_HEADER(utility)
00032 #include GALOIS_CXX11_STD_HEADER(vector)
00033 #include <stdexcept>
00034
00035 namespace Galois {
00036
00038 template<
00039 class _Key,
00040 class _Tp,
00041 class _Compare = std::less<_Key>,
00042 class _Alloc = std::allocator<std::pair<_Key, _Tp> >
00043 >
00044 class flat_map {
00045 public:
00046 typedef _Key key_type;
00047 typedef _Tp mapped_type;
00048 typedef std::pair<_Key, _Tp> value_type;
00049 typedef _Compare key_compare;
00050 typedef _Alloc allocator_type;
00051
00052 class value_compare
00053 : public std::binary_function<value_type, value_type, bool> {
00054 friend class flat_map<_Key, _Tp, _Compare, _Alloc>;
00055 protected:
00056 _Compare comp;
00057
00058 value_compare(_Compare __c): comp(__c) { }
00059 public:
00060 bool operator()(const value_type& __x, const value_type& __y) const {
00061 return comp(__x.first, __y.first);
00062 }
00063 };
00064
00065
00066 private:
00067
00069 typedef typename _Alloc::template rebind<value_type>::other _Pair_alloc_type;
00070
00071 typedef std::vector<value_type, _Pair_alloc_type> _VectTy;
00072 _VectTy _data;
00073 _Compare _comp;
00074
00075 class value_key_compare
00076 : public std::binary_function<value_type, key_type, bool> {
00077 friend class flat_map<_Key, _Tp, _Compare, _Alloc>;
00078 protected:
00079 _Compare comp;
00080
00081 value_key_compare(_Compare __c): comp(__c) { }
00082 public:
00083 bool operator()(const value_type& __x, const key_type& __y) const {
00084 return comp(__x.first, __y);
00085 }
00086 };
00087
00088 value_key_compare value_key_comp() const { return value_key_compare(key_comp()); }
00089
00090 bool key_eq(const key_type& k1, const key_type& k2) const {
00091 return !key_comp()(k1, k2) && !key_comp()(k2, k1);
00092 }
00093
00094 void resort() {
00095 std::sort(_data.begin(), _data.end(), value_comp());
00096 }
00097
00098
00099 public:
00100 typedef typename _Pair_alloc_type::pointer pointer;
00101 typedef typename _Pair_alloc_type::const_pointer const_pointer;
00102 typedef typename _Pair_alloc_type::reference reference;
00103 typedef typename _Pair_alloc_type::const_reference const_reference;
00104 typedef typename _VectTy::iterator iterator;
00105 typedef typename _VectTy::const_iterator const_iterator;
00106 typedef typename _VectTy::size_type size_type;
00107 typedef typename _VectTy::difference_type difference_type;
00108 typedef typename _VectTy::reverse_iterator reverse_iterator;
00109 typedef typename _VectTy::const_reverse_iterator const_reverse_iterator;
00110
00111 flat_map() :_data(), _comp() {}
00112
00113 explicit flat_map(const _Compare& __comp,
00114 const allocator_type& __a = allocator_type())
00115 :_data(_Pair_alloc_type(__a)), _comp(__comp) {}
00116
00117 flat_map(const flat_map& __x) :_data(__x._data), _comp(__x._comp) {}
00118
00119 flat_map(flat_map&& __x)
00120
00121 : _data(std::move(__x._data)), _comp(std::move(__x._comp)) {}
00122
00123
00124
00125
00126
00127
00128
00129
00130 template<typename _InputIterator>
00131 flat_map(_InputIterator __first, _InputIterator __last)
00132 : _data(__first, __last), _comp() { resort(); }
00133
00134 template<typename _InputIterator>
00135 flat_map(_InputIterator __first, _InputIterator __last,
00136 const _Compare& __comp,
00137 const allocator_type& __a = allocator_type())
00138 : _data(__first, __last, _Pair_alloc_type(__a)) {
00139 resort();
00140 }
00141
00142 flat_map& operator=(const flat_map& __x) {
00143 _data = __x._data;
00144 _comp = __x._comp;
00145 return *this;
00146 }
00147
00148 flat_map& operator=(flat_map&& __x) {
00149 clear();
00150 swap(__x);
00151 return *this;
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 allocator_type get_allocator() const {
00163 return allocator_type(_data.get_allocator());
00164 }
00165
00166
00167
00168 iterator begin() { return _data.begin(); }
00169 const_iterator begin() const { return _data.begin(); }
00170 iterator end() { return _data.end(); }
00171 const_iterator end() const { return _data.end(); }
00172 reverse_iterator rbegin() { return _data.rbegin(); }
00173 const_reverse_iterator rbegin() const { return _data.rbegin(); }
00174 reverse_iterator rend() { return _data.rend(); }
00175 const_reverse_iterator rend() const { return _data.rend(); }
00176 const_iterator cbegin() const { return _data.begin(); }
00177 const_iterator cend() const { return _data.end(); }
00178 const_reverse_iterator crbegin() const { return _data.rbegin(); }
00179 const_reverse_iterator crend() const { return _data.rend(); }
00180
00181 bool empty() const { return _data.empty(); }
00182 size_type size() const { return _data.size(); }
00183 size_type max_size() const { return _data.max_size(); }
00184
00185 mapped_type& operator[](const key_type& __k) {
00186 iterator __i = lower_bound(__k);
00187
00188 if (__i == end() || key_comp()(__k, (*__i).first))
00189
00190
00191
00192 #ifndef GALOIS_CXX11_VECTOR_HAS_NO_EMPLACE
00193 __i = _data.emplace(__i, __k, mapped_type());
00194 #else
00195 __i = _data.insert(__i, value_type(__k, mapped_type()));
00196 #endif
00197 return (*__i).second;
00198 }
00199
00200 mapped_type& operator[](key_type&& __k) {
00201 iterator __i = lower_bound(__k);
00202
00203 if (__i == end() || key_comp()(__k, (*__i).first))
00204
00205
00206
00207 #ifndef GALOIS_CXX11_VECTOR_HAS_NO_EMPLACE
00208 __i = _data.emplace(__i, std::move(__k), mapped_type());
00209 #else
00210 __i = _data.insert(__i, value_type(std::move(__k), mapped_type()));
00211 #endif
00212 return (*__i).second;
00213 }
00214
00215 mapped_type& at(const key_type& __k) {
00216 iterator __i = lower_bound(__k);
00217 if (__i == end() || key_comp()(__k, (*__i).first))
00218 throw std::out_of_range(__N("flat_map::at"));
00219 return (*__i).second;
00220 }
00221
00222 const mapped_type& at(const key_type& __k) const {
00223 const_iterator __i = lower_bound(__k);
00224 if (__i == end() || key_comp()(__k, (*__i).first))
00225 throw std::out_of_range(__N("flat_map::at"));
00226 return (*__i).second;
00227 }
00228
00229 std::pair<iterator, bool> insert(const value_type& __x) {
00230 auto i = lower_bound(__x.first);
00231 if (i != end() && key_eq(i->first, __x.first))
00232 return std::make_pair(i, false);
00233 return std::make_pair(_data.insert(i, __x), true);
00234 }
00235
00236
00237 template<typename _Pair>
00238 std::pair<iterator, bool> insert(_Pair&& __x) {
00239 auto i = lower_bound(__x.first);
00240 if (i != end() && key_eq(i->first, __x.first))
00241 return std::make_pair(i, false);
00242 return std::make_pair(_data.insert(i, std::forward<_Pair>(__x)), true);
00243 }
00244
00245
00246
00247
00248
00249
00250
00251 iterator insert(const_iterator __position, const value_type& __x) {
00252 return insert(__x).first;
00253 }
00254
00255
00256 template<typename _Pair>
00257 iterator insert(const_iterator __position, _Pair&& __x) {
00258 return insert(std::forward<_Pair>(__x)).first;
00259 }
00260
00261 template<typename _InputIterator>
00262 void insert(_InputIterator __first, _InputIterator __last) {
00263 while (__first != __last)
00264 insert(*__first++);
00265 }
00266
00267 iterator erase(const_iterator __position) { return _data.erase(__position); }
00268 iterator erase(iterator __position) { return _data.erase(__position); }
00269
00270 size_type erase(const key_type& __x) {
00271 auto i = find(__x);
00272 if (key_eq(__x, i->first)) {
00273 _data.erase(i);
00274 return 1;
00275 }
00276 return 0;
00277 }
00278
00279 iterator erase(const_iterator __first, const_iterator __last) {
00280 return _data.erase(__first, __last);
00281 }
00282
00283 void swap(flat_map& __x) { _data.swap(__x._data); std::swap(_comp, __x._comp); }
00284
00285 void clear() { _data.clear(); }
00286
00287 key_compare key_comp() const { return _comp; }
00288 value_compare value_comp() const { return value_compare(key_comp()); }
00289
00290 iterator find(const key_type& __x) {
00291 auto i = lower_bound(__x);
00292 if (key_eq(i->first, __x))
00293 return i;
00294 return end();
00295 }
00296
00297 const_iterator find(const key_type& __x) const {
00298 auto i = lower_bound(__x);
00299 if (key_eq(i->first, __x))
00300 return i;
00301 return end();
00302 }
00303
00304 size_type count(const key_type& __x) const { return find(__x) == end() ? 0 : 1; }
00305
00306 iterator lower_bound(const key_type& __x) {
00307 return std::lower_bound(_data.begin(), _data.end(), __x, value_key_comp());
00308 }
00309 const_iterator lower_bound(const key_type& __x) const {
00310 return std::lower_bound(_data.begin(), _data.end(), __x, value_key_comp());
00311 }
00312
00313 iterator upper_bound(const key_type& __x) {
00314 return std::upper_bound(_data.begin(), _data.end(), __x, value_key_comp());
00315 }
00316 const_iterator upper_bound(const key_type& __x) const {
00317 return std::upper_bound(_data.begin(), _data.end(), __x, value_key_comp());
00318 }
00319
00320 std::pair<iterator, iterator> equal_range(const key_type& __x) {
00321 return std::make_pair(lower_bound(__x), upper_bound(__x));
00322 }
00323
00324 std::pair<const_iterator, const_iterator> equal_range(const key_type& __x) const {
00325 return std::make_pair(lower_bound(__x), upper_bound(__x));
00326 }
00327
00328 template<typename _K1, typename _T1, typename _C1, typename _A1>
00329 friend bool operator==(const flat_map<_K1, _T1, _C1, _A1>&,
00330 const flat_map<_K1, _T1, _C1, _A1>&);
00331
00332 template<typename _K1, typename _T1, typename _C1, typename _A1>
00333 friend bool operator<(const flat_map<_K1, _T1, _C1, _A1>&,
00334 const flat_map<_K1, _T1, _C1, _A1>&);
00335 };
00336
00337 template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
00338 inline bool operator==(const flat_map<_Key, _Tp, _Compare, _Alloc>& __x,
00339 const flat_map<_Key, _Tp, _Compare, _Alloc>& __y) {
00340 return __x._data == __y._data;
00341 }
00342
00343
00344 template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
00345 inline bool operator<(const flat_map<_Key, _Tp, _Compare, _Alloc>& __x,
00346 const flat_map<_Key, _Tp, _Compare, _Alloc>& __y) {
00347 return __x._data < __y._data;
00348 }
00349
00351 template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
00352 inline bool operator!=(const flat_map<_Key, _Tp, _Compare, _Alloc>& __x,
00353 const flat_map<_Key, _Tp, _Compare, _Alloc>& __y) {
00354 return !(__x == __y);
00355 }
00356
00358 template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
00359 inline bool operator>(const flat_map<_Key, _Tp, _Compare, _Alloc>& __x,
00360 const flat_map<_Key, _Tp, _Compare, _Alloc>& __y) {
00361 return __y < __x;
00362 }
00363
00365 template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
00366 inline bool operator<=(const flat_map<_Key, _Tp, _Compare, _Alloc>& __x,
00367 const flat_map<_Key, _Tp, _Compare, _Alloc>& __y) {
00368 return !(__y < __x);
00369 }
00370
00372 template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
00373 inline bool operator>=(const flat_map<_Key, _Tp, _Compare, _Alloc>& __x,
00374 const flat_map<_Key, _Tp, _Compare, _Alloc>& __y) {
00375 return !(__x < __y);
00376 }
00377
00378 }
00379
00380 namespace std {
00381
00383 template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
00384 inline void swap(Galois::flat_map<_Key, _Tp, _Compare, _Alloc>& __x,
00385 Galois::flat_map<_Key, _Tp, _Compare, _Alloc>& __y) {
00386 __x.swap(__y);
00387 }
00388
00389 }
00390
00391 #endif