• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

MyGUI_BiIndexBase.h

Go to the documentation of this file.
00001 
00007 /*
00008     This file is part of MyGUI.
00009 
00010     MyGUI is free software: you can redistribute it and/or modify
00011     it under the terms of the GNU Lesser General Public License as published by
00012     the Free Software Foundation, either version 3 of the License, or
00013     (at your option) any later version.
00014 
00015     MyGUI is distributed in the hope that it will be useful,
00016     but WITHOUT ANY WARRANTY; without even the implied warranty of
00017     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018     GNU Lesser General Public License for more details.
00019 
00020     You should have received a copy of the GNU Lesser General Public License
00021     along with MyGUI.  If not, see <http://www.gnu.org/licenses/>.
00022 */
00023 #ifndef __MYGUI_BIINDEX_BASE_H__
00024 #define __MYGUI_BIINDEX_BASE_H__
00025 
00026 #include "MyGUI_Prerequest.h"
00027 #include "MyGUI_Common.h"
00028 
00029 namespace MyGUI
00030 {
00031 
00032     class BiIndexBase
00033     {
00034     public:
00035         virtual ~BiIndexBase() { }
00036     protected:
00037 
00038         size_t getIndexCount() { return mIndexFace.size(); }
00039 
00040         size_t insertItemAt(size_t _index)
00041         {
00042             #if MYGUI_DEBUG_MODE == 1
00043                 MYGUI_ASSERT_RANGE_INSERT(_index, mIndexFace.size(), "BiIndexBase::insertItemAt");
00044                 checkIndexes();
00045             #endif
00046 
00047             if (_index == MyGUI::ITEM_NONE) _index = mIndexFace.size();
00048 
00049             size_t index;
00050 
00051             if (_index == mIndexFace.size())
00052             {
00053                 // для вставки айтема
00054                 index = mIndexFace.size();
00055 
00056                 mIndexFace.push_back(_index);
00057                 mIndexBack.push_back(_index);
00058             }
00059             else
00060             {
00061                 // для вставки айтема
00062                 index = mIndexFace[_index];
00063 
00064                 size_t count = mIndexFace.size();
00065                 for (size_t pos=0; pos<count; ++pos)
00066                 {
00067                     if (mIndexFace[pos] >= index) mIndexFace[pos]++;
00068                 }
00069                 mIndexFace.insert(mIndexFace.begin() + _index, index);
00070 
00071                 count ++;
00072                 mIndexBack.push_back(0);
00073                 for (size_t pos=0; pos<count; ++pos)
00074                 {
00075                     mIndexBack[mIndexFace[pos]] = pos;
00076                 }
00077             }
00078 
00079             #if MYGUI_DEBUG_MODE == 1
00080                 checkIndexes();
00081             #endif
00082 
00083             return index;
00084         }
00085 
00086         size_t removeItemAt(size_t _index)
00087         {
00088             #if MYGUI_DEBUG_MODE == 1
00089                 MYGUI_ASSERT_RANGE(_index, mIndexFace.size(), "BiIndexBase::removeItemAt");
00090                 checkIndexes();
00091             #endif
00092 
00093             // для удаления айтема
00094             size_t index = mIndexFace[_index];
00095 
00096             mIndexFace.erase(mIndexFace.begin() + _index);
00097             mIndexBack.pop_back();
00098 
00099             size_t count = mIndexFace.size();
00100             for (size_t pos=0; pos<count; ++pos)
00101             {
00102                 if (mIndexFace[pos] > index) mIndexFace[pos]--;
00103                 mIndexBack[mIndexFace[pos]] = pos;
00104             }
00105 
00106             #if MYGUI_DEBUG_MODE == 1
00107                 checkIndexes();
00108             #endif
00109 
00110             return index;
00111         }
00112 
00113         void removeAllItems()
00114         {
00115             mIndexFace.clear();
00116             mIndexBack.clear();
00117         }
00118 
00119         // на входе индексы пользователя, на выходе реальные индексы
00120         size_t convertToBack(size_t _index)
00121         {
00122             #if MYGUI_DEBUG_MODE == 1
00123                 MYGUI_ASSERT_RANGE_AND_NONE(_index, mIndexFace.size(), "BiIndexBase::convertToBack");
00124             #endif
00125             return _index == ITEM_NONE ? ITEM_NONE : mIndexFace[_index];
00126         }
00127 
00128         // на входе индексы реальные, на выходе, то что видит пользователь
00129         size_t convertToFace(size_t _index)
00130         {
00131             #if MYGUI_DEBUG_MODE == 1
00132                 MYGUI_ASSERT_RANGE_AND_NONE(_index, mIndexFace.size(), "BiIndexBase::convertToFace");
00133             #endif
00134             return _index == ITEM_NONE ? ITEM_NONE : mIndexBack[_index];
00135         }
00136 
00137         // меняет местами два индекса, индексы со стороны пользователя
00138         void swapItemsFaceAt(size_t _index1, size_t _index2)
00139         {
00140             #if MYGUI_DEBUG_MODE == 1
00141                 MYGUI_ASSERT_RANGE(_index1, mIndexFace.size(), "BiIndexBase::swapItemsFaceAt");
00142                 MYGUI_ASSERT_RANGE(_index2, mIndexFace.size(), "BiIndexBase::swapItemsFaceAt");
00143             #endif
00144 
00145             std::swap(mIndexFace[_index1], mIndexFace[_index2]);
00146             std::swap(mIndexBack[mIndexFace[_index1]], mIndexBack[mIndexFace[_index2]]);
00147         }
00148 
00149         // меняет местами два индекса, индексы со сторонны данных
00150         void swapItemsBackAt(size_t _index1, size_t _index2)
00151         {
00152             #if MYGUI_DEBUG_MODE == 1
00153                 MYGUI_ASSERT_RANGE(_index1, mIndexFace.size(), "BiIndexBase::swapItemsBackAt");
00154                 MYGUI_ASSERT_RANGE(_index2, mIndexFace.size(), "BiIndexBase::swapItemsBackAt");
00155             #endif
00156 
00157             std::swap(mIndexBack[_index1], mIndexBack[_index2]);
00158             std::swap(mIndexFace[mIndexBack[_index1]], mIndexFace[mIndexBack[_index2]]);
00159         }
00160 
00161         #if MYGUI_DEBUG_MODE == 1
00162 
00163         void checkIndexes()
00164         {
00165             assert(mIndexFace.size() == mIndexBack.size());
00166 
00167             // проверяем на уникальность каждого индекса в маппинге
00168             std::vector<bool> vec;
00169             size_t count = mIndexFace.size();
00170 
00171             vec.reserve(count);
00172             for (size_t pos=0; pos<count; ++pos) vec.push_back(false);
00173 
00174             for (size_t pos=0; pos<count; ++pos)
00175             {
00176                 // максимум
00177                 size_t index = mIndexBack[pos];
00178                 if (index >= count) throw new std::exception();
00179 
00180                 // максимум
00181                 index = mIndexFace[pos];
00182                 if (index >= count) throw new std::exception();
00183 
00184                 if (vec[index]) throw new std::exception();
00185                 vec[index] = true;
00186             }
00187 
00188             for (size_t pos=0; pos<count; ++pos)
00189             {
00190                 if (!vec[pos]) throw new std::exception();
00191             }
00192 
00193             // проверяем на взаимоссылаемость индексов
00194             for (size_t pos=0; pos<count; ++pos)
00195             {
00196                 size_t index = mIndexFace[pos];
00197                 if (mIndexBack[index] != pos) throw new std::exception();
00198             }
00199         }
00200 
00201         #endif
00202 
00203     private:
00204         typedef std::vector<size_t> VectorSizeT;
00205 
00206         // маппинг с индексов, которые видны наружу
00207         // на индексы которые реально используются данными
00208         VectorSizeT mIndexFace;
00209 
00210         // маппинг с индексов, которые используют данные
00211         // на индексы которые виндны наружу
00212         VectorSizeT mIndexBack;
00213     };
00214 
00215 } // namespace MyGUI
00216 
00217 #endif // __MYGUI_BIINDEX_BASE_H__

Generated on Sun Jan 30 2011 for MyGUI by  doxygen 1.7.1