Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifndef sorted_map_INCLUDED
00038 #define sorted_map_INCLUDED
00039
00040
00041
00042 #if defined(defs_INCLUDED) && !defined(USE_STANDARD_TYPES)
00043 #undef short
00044 #undef int
00045 #undef long
00046 #endif // defined(defs_INCLUDED) && !defined(USE_STANDARD_TYPES)
00047
00048 #ifndef __GNUC__
00049 #include <CC/pair.h>
00050 #include <CC/vector.h>
00051 #else
00052 #include "pair.h"
00053 #include "vector.h"
00054 #endif
00055
00056 template <class KEY, class RANGE>
00057 struct SORTED_MAP
00058 {
00059 public:
00060
00061 typedef pair<KEY, RANGE> MAP_ELEMENT;
00062 typedef vector<MAP_ELEMENT> MAP_VECTOR;
00063 typedef MAP_VECTOR::size_type MAP_SIZE;
00064
00065 private:
00066
00067 BOOL _sorted;
00068 MAP_SIZE _chunksize;
00069 MAP_VECTOR _map;
00070
00071 MAP_SIZE _binary_search(MAP_SIZE from, MAP_SIZE till, KEY k);
00072
00073 void _sort()
00074 {
00075 _sorted = TRUE;
00076 FmtAssert(FALSE, ("Map must be created in sorted order!"));
00077 }
00078
00079 BOOL _is_sorted() const
00080 {
00081 BOOL sorted = TRUE;
00082 INT32 size = _map.size();
00083
00084 if (INT32 i = 0; sorted && i < size-1; i++)
00085 sorted = _map[i].first < _map[i+1].first;
00086 return sorted;
00087 }
00088
00089 public:
00090
00091 SORTED_MAP(): _chunksize(0), _sorted(TRUE), _map() {}
00092
00093 SORTED_MAP(MAP_SIZE chunksize):
00094 _chunksize(chunksize), _sorted(TRUE), _map() {}
00095
00096 SORTED_MAP(const MAP_VECTOR &vector): _sorted(TRUE), _map(vector)
00097 {
00098 _sorted = _is_sorted();
00099 }
00100
00101 bool empty() const
00102 {
00103 return _map.empty();
00104 }
00105
00106 MAP_SIZE size() const
00107 {
00108 return _map.size();
00109 }
00110
00111 MAP_SIZE capacity() const
00112 {
00113 return _map.capacity();
00114 }
00115
00116 void clear()
00117 {
00118 _map.clear();
00119 _sorted = TRUE;
00120 }
00121
00122 void push_back(const MAP_ELEMENT &amap)
00123 {
00124 if (_chunksize > 0 && _map.size() == _map.capacity())
00125 _map.reserve(_map.capacity() + _chunksize);
00126 if (_sorted && !empty() && (amap.first < _map.back().first))
00127 _sorted = FALSE;
00128 _map.push_back(amap);
00129 }
00130
00131 const RANGE &operator[] (KEY k) const
00132 {
00133 const MAP_SIZE idx = _binary_search(0, _map.size()-1, k);
00134 Is_True(idx < _map.size() && _map[idx].first == k,
00135 ("Attempt to access non-existent element!"));
00136 return _map[idx].second;
00137 }
00138
00139 RANGE &operator[] (KEY k)
00140 {
00141 const MAP_SIZE idx = _binary_search(0, _map.size()-1, k);
00142 Is_True(idx < _map.size() && _map[idx].first == k,
00143 ("Attempt to access non-existent element!"));
00144 return _map[idx].second;
00145 }
00146
00147 };
00148
00149
00150 template <class KEY, class RANGE>
00151 SORTED_MAP<KEY, RANGE>::MAP_SIZE
00152 SORTED_MAP<KEY, RANGE>::_binary_search(MAP_SIZE from,
00153 MAP_SIZE till,
00154 KEY k)
00155 {
00156
00157
00158
00159
00160 MAP_SIZE idx;
00161
00162 if (!_sorted)
00163 _sort();
00164
00165 if (from >= till)
00166 idx = from;
00167 else
00168 {
00169 const INT32 halfway = (from + till)/2;
00170 const KEY k2 = _map[halfway].first;
00171
00172 if (k == k2)
00173 idx = halfway;
00174 else if (k < k2)
00175 idx = ((halfway == 0)? 0 : _binary_search(from, halfway-1, k));
00176 else
00177 idx =_binary_search(halfway+1, till, k);
00178 }
00179 return idx;
00180 }
00181
00182 #endif