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