00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef __MYGUI_BIINDEX_BASE_H__
00024 #define __MYGUI_BIINDEX_BASE_H__
00025
00026 #include "MyGUI_Prerequest.h"
00027
00028 namespace MyGUI
00029 {
00030
00031 class BiIndexBase
00032 {
00033 public:
00034 virtual ~BiIndexBase() { }
00035 protected:
00036
00037 size_t getIndexCount() { return mIndexFace.size(); }
00038
00039 size_t insertItemAt(size_t _index)
00040 {
00041 #if MYGUI_DEBUG_MODE == 1
00042 MYGUI_ASSERT_RANGE_INSERT(_index, mIndexFace.size(), "BiIndexBase::insertItemAt");
00043 checkIndexes();
00044 #endif
00045
00046 if (_index == MyGUI::ITEM_NONE) _index = mIndexFace.size();
00047
00048 size_t index;
00049
00050 if (_index == mIndexFace.size())
00051 {
00052
00053 index = mIndexFace.size();
00054
00055 mIndexFace.push_back(_index);
00056 mIndexBack.push_back(_index);
00057 }
00058 else
00059 {
00060
00061 index = mIndexFace[_index];
00062
00063 size_t count = mIndexFace.size();
00064 for (size_t pos=0; pos<count; ++pos)
00065 {
00066 if (mIndexFace[pos] >= index) mIndexFace[pos]++;
00067 }
00068 mIndexFace.insert(mIndexFace.begin() + _index, index);
00069
00070 count ++;
00071 mIndexBack.push_back(0);
00072 for (size_t pos=0; pos<count; ++pos)
00073 {
00074 mIndexBack[mIndexFace[pos]] = pos;
00075 }
00076 }
00077
00078 #if MYGUI_DEBUG_MODE == 1
00079 checkIndexes();
00080 #endif
00081
00082 return index;
00083 }
00084
00085 size_t removeItemAt(size_t _index)
00086 {
00087 #if MYGUI_DEBUG_MODE == 1
00088 MYGUI_ASSERT_RANGE(_index, mIndexFace.size(), "BiIndexBase::removeItemAt");
00089 checkIndexes();
00090 #endif
00091
00092
00093 size_t index = mIndexFace[_index];
00094
00095 mIndexFace.erase(mIndexFace.begin() + _index);
00096 mIndexBack.pop_back();
00097
00098 size_t count = mIndexFace.size();
00099 for (size_t pos=0; pos<count; ++pos)
00100 {
00101 if (mIndexFace[pos] > index) mIndexFace[pos]--;
00102 mIndexBack[mIndexFace[pos]] = pos;
00103 }
00104
00105 #if MYGUI_DEBUG_MODE == 1
00106 checkIndexes();
00107 #endif
00108
00109 return index;
00110 }
00111
00112 void removeAllItems()
00113 {
00114 mIndexFace.clear();
00115 mIndexBack.clear();
00116 }
00117
00118
00119 size_t convertToBack(size_t _index) const
00120 {
00121 #if MYGUI_DEBUG_MODE == 1
00122 MYGUI_ASSERT_RANGE_AND_NONE(_index, mIndexFace.size(), "BiIndexBase::convertToBack");
00123 #endif
00124 return _index == ITEM_NONE ? ITEM_NONE : mIndexFace[_index];
00125 }
00126
00127
00128 size_t convertToFace(size_t _index) const
00129 {
00130 #if MYGUI_DEBUG_MODE == 1
00131 MYGUI_ASSERT_RANGE_AND_NONE(_index, mIndexFace.size(), "BiIndexBase::convertToFace");
00132 #endif
00133 return _index == ITEM_NONE ? ITEM_NONE : mIndexBack[_index];
00134 }
00135
00136
00137 void swapItemsFaceAt(size_t _index1, size_t _index2)
00138 {
00139 #if MYGUI_DEBUG_MODE == 1
00140 MYGUI_ASSERT_RANGE(_index1, mIndexFace.size(), "BiIndexBase::swapItemsFaceAt");
00141 MYGUI_ASSERT_RANGE(_index2, mIndexFace.size(), "BiIndexBase::swapItemsFaceAt");
00142 #endif
00143
00144 std::swap(mIndexFace[_index1], mIndexFace[_index2]);
00145 std::swap(mIndexBack[mIndexFace[_index1]], mIndexBack[mIndexFace[_index2]]);
00146 }
00147
00148
00149 void swapItemsBackAt(size_t _index1, size_t _index2)
00150 {
00151 #if MYGUI_DEBUG_MODE == 1
00152 MYGUI_ASSERT_RANGE(_index1, mIndexFace.size(), "BiIndexBase::swapItemsBackAt");
00153 MYGUI_ASSERT_RANGE(_index2, mIndexFace.size(), "BiIndexBase::swapItemsBackAt");
00154 #endif
00155
00156 std::swap(mIndexBack[_index1], mIndexBack[_index2]);
00157 std::swap(mIndexFace[mIndexBack[_index1]], mIndexFace[mIndexBack[_index2]]);
00158 }
00159
00160 #if MYGUI_DEBUG_MODE == 1
00161
00162 void checkIndexes()
00163 {
00164 assert(mIndexFace.size() == mIndexBack.size());
00165
00166
00167 std::vector<bool> vec;
00168 size_t count = mIndexFace.size();
00169
00170 vec.reserve(count);
00171 for (size_t pos=0; pos<count; ++pos) vec.push_back(false);
00172
00173 for (size_t pos=0; pos<count; ++pos)
00174 {
00175
00176 size_t index = mIndexBack[pos];
00177 if (index >= count) throw new std::exception();
00178
00179
00180 index = mIndexFace[pos];
00181 if (index >= count) throw new std::exception();
00182
00183 if (vec[index]) throw new std::exception();
00184 vec[index] = true;
00185 }
00186
00187 for (size_t pos=0; pos<count; ++pos)
00188 {
00189 if (!vec[pos]) throw new std::exception();
00190 }
00191
00192
00193 for (size_t pos=0; pos<count; ++pos)
00194 {
00195 size_t index = mIndexFace[pos];
00196 if (mIndexBack[index] != pos) throw new std::exception();
00197 }
00198 }
00199
00200 #endif
00201
00202 private:
00203 typedef std::vector<size_t> VectorSizeT;
00204
00205
00206
00207 VectorSizeT mIndexFace;
00208
00209
00210
00211 VectorSizeT mIndexBack;
00212 };
00213
00214 }
00215
00216 #endif // __MYGUI_BIINDEX_BASE_H__