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