MyGUI 3.2.0

- Main Page
- Related Pages
- Namespaces
- Data Structures
- Files
- Examples

- File List
- Globals

MyGUI_BiIndexBase.cpp
Go to the documentation of this file.
1
6 /*
7 This file is part of MyGUI.
8
9 MyGUI is free software: you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 MyGUI is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public License
20 along with MyGUI. If not, see <http://www.gnu.org/licenses/>.
21 */
22 #include "MyGUI_Precompiled.h"
23 #include "MyGUI_BiIndexBase.h"
24
25 namespace MyGUI
26 {
27
28 BiIndexBase::BiIndexBase()
29 {
30 }
31
32 BiIndexBase::~BiIndexBase()
33 {
34 }
35
36 size_t BiIndexBase::getIndexCount() const
37 {
38 return mIndexFace.size();
39 }
40
41 size_t BiIndexBase::insertItemAt(size_t _index)
42 {
43 #if MYGUI_DEBUG_MODE == 1
44 MYGUI_ASSERT_RANGE_INSERT(_index, mIndexFace.size(), "BiIndexBase::insertItemAt");
45 checkIndexes();
46 #endif
47
48 if (_index == MyGUI::ITEM_NONE)
49 _index = mIndexFace.size();
50
51 size_t index;
52
53 if (_index == mIndexFace.size())
54 {
55 // для вставки айтема
56 index = mIndexFace.size();
57
58 mIndexFace.push_back(_index);
59 mIndexBack.push_back(_index);
60 }
61 else
62 {
63 // для вставки айтема
64 index = mIndexFace[_index];
65
66 size_t count = mIndexFace.size();
67 for (size_t pos = 0; pos < count; ++pos)
68 {
69 if (mIndexFace[pos] >= index)
70 mIndexFace[pos]++;
71 }
72 mIndexFace.insert(mIndexFace.begin() + _index, index);
73
74 count ++;
75 mIndexBack.push_back(0);
76 for (size_t pos = 0; pos < count; ++pos)
77 {
78 mIndexBack[mIndexFace[pos]] = pos;
79 }
80 }
81
82 #if MYGUI_DEBUG_MODE == 1
83 checkIndexes();
84 #endif
85
86 return index;
87 }
88
89 size_t BiIndexBase::removeItemAt(size_t _index)
90 {
91 #if MYGUI_DEBUG_MODE == 1
92 MYGUI_ASSERT_RANGE(_index, mIndexFace.size(), "BiIndexBase::removeItemAt");
93 checkIndexes();
94 #endif
95
96 // для удаления айтема
97 size_t index = mIndexFace[_index];
98
99 mIndexFace.erase(mIndexFace.begin() + _index);
100 mIndexBack.pop_back();
101
102 size_t count = mIndexFace.size();
103 for (size_t pos = 0; pos < count; ++pos)
104 {
105 if (mIndexFace[pos] > index)
106 mIndexFace[pos]--;
107 mIndexBack[mIndexFace[pos]] = pos;
108 }
109
110 #if MYGUI_DEBUG_MODE == 1
111 checkIndexes();
112 #endif
113
114 return index;
115 }
116
117 void BiIndexBase::removeAllItems()
118 {
119 mIndexFace.clear();
120 mIndexBack.clear();
121 }
122
123 // на входе индексы пользователя, на выходе реальные индексы
124 size_t BiIndexBase::convertToBack(size_t _index) const
125 {
126 #if MYGUI_DEBUG_MODE == 1
127 MYGUI_ASSERT_RANGE_AND_NONE(_index, mIndexFace.size(), "BiIndexBase::convertToBack");
128 #endif
129 return _index == ITEM_NONE ? ITEM_NONE : mIndexFace[_index];
130 }
131
132 // на входе индексы реальные, на выходе, то что видит пользователь
133 size_t BiIndexBase::convertToFace(size_t _index) const
134 {
135 #if MYGUI_DEBUG_MODE == 1
136 MYGUI_ASSERT_RANGE_AND_NONE(_index, mIndexFace.size(), "BiIndexBase::convertToFace");
137 #endif
138 return _index == ITEM_NONE ? ITEM_NONE : mIndexBack[_index];
139 }
140
141 // меняет местами два индекса, индексы со стороны пользователя
142 void BiIndexBase::swapItemsFaceAt(size_t _index1, size_t _index2)
143 {
144 #if MYGUI_DEBUG_MODE == 1
145 MYGUI_ASSERT_RANGE(_index1, mIndexFace.size(), "BiIndexBase::swapItemsFaceAt");
146 MYGUI_ASSERT_RANGE(_index2, mIndexFace.size(), "BiIndexBase::swapItemsFaceAt");
147 #endif
148
149 std::swap(mIndexFace[_index1], mIndexFace[_index2]);
150 std::swap(mIndexBack[mIndexFace[_index1]], mIndexBack[mIndexFace[_index2]]);
151 }
152
153 // меняет местами два индекса, индексы со сторонны данных
154 void BiIndexBase::swapItemsBackAt(size_t _index1, size_t _index2)
155 {
156 #if MYGUI_DEBUG_MODE == 1
157 MYGUI_ASSERT_RANGE(_index1, mIndexFace.size(), "BiIndexBase::swapItemsBackAt");
158 MYGUI_ASSERT_RANGE(_index2, mIndexFace.size(), "BiIndexBase::swapItemsBackAt");
159 #endif
160
161 std::swap(mIndexBack[_index1], mIndexBack[_index2]);
162 std::swap(mIndexFace[mIndexBack[_index1]], mIndexFace[mIndexBack[_index2]]);
163 }
164
165 #if MYGUI_DEBUG_MODE == 1
166
167 void BiIndexBase::checkIndexes()
168 {
169 assert(mIndexFace.size() == mIndexBack.size());
170
171 // проверяем на уникальность каждого индекса в маппинге
172 std::vector<bool> vec;
173 size_t count = mIndexFace.size();
174
175 vec.reserve(count);
176 for (size_t pos = 0; pos < count; ++pos)
177 vec.push_back(false);
178
179 for (size_t pos = 0; pos < count; ++pos)
180 {
181 // максимум
182 size_t index = mIndexBack[pos];
183 if (index >= count)
184 throw new std::exception();
185
186 // максимум
187 index = mIndexFace[pos];
188 if (index >= count)
189 throw new std::exception();
190
191 if (vec[index])
192 throw new std::exception();
193 vec[index] = true;
194 }
195
196 for (size_t pos = 0; pos < count; ++pos)
197 {
198 if (!vec[pos])
199 throw new std::exception();
200 }
201
202 // проверяем на взаимоссылаемость индексов
203 for (size_t pos = 0; pos < count; ++pos)
204 {
205 size_t index = mIndexFace[pos];
206 if (mIndexBack[index] != pos)
207 throw new std::exception();
208 }
209 }
210
211 #endif
212
213 } // namespace MyGUI
MyGUI_Precompiled.h
MyGUI::BiIndexBase::removeItemAt
size_t removeItemAt(size_t _index)
Definition: MyGUI_BiIndexBase.cpp:89
MyGUI::BiIndexBase::convertToFace
size_t convertToFace(size_t _index) const
Definition: MyGUI_BiIndexBase.cpp:133
MyGUI::BiIndexBase::swapItemsBackAt
void swapItemsBackAt(size_t _index1, size_t _index2)
Definition: MyGUI_BiIndexBase.cpp:154
MyGUI::ITEM_NONE
const size_t ITEM_NONE
Definition: MyGUI_Macros.h:32
MyGUI::BiIndexBase::insertItemAt
size_t insertItemAt(size_t _index)
Definition: MyGUI_BiIndexBase.cpp:41
MyGUI::BiIndexBase::getIndexCount
size_t getIndexCount() const
Definition: MyGUI_BiIndexBase.cpp:36
MyGUI::BiIndexBase::removeAllItems
void removeAllItems()
Definition: MyGUI_BiIndexBase.cpp:117
MYGUI_ASSERT_RANGE_AND_NONE
#define MYGUI_ASSERT_RANGE_AND_NONE(index, size, owner)
Definition: MyGUI_Diagnostic.h:71
MyGUI_BiIndexBase.h
MYGUI_ASSERT_RANGE
#define MYGUI_ASSERT_RANGE(index, size, owner)
Definition: MyGUI_Diagnostic.h:70
MyGUI::BiIndexBase::swapItemsFaceAt
void swapItemsFaceAt(size_t _index1, size_t _index2)
Definition: MyGUI_BiIndexBase.cpp:142
MyGUI::BiIndexBase::convertToBack
size_t convertToBack(size_t _index) const
Definition: MyGUI_BiIndexBase.cpp:124
MyGUI::BiIndexBase::~BiIndexBase
virtual ~BiIndexBase()
Definition: MyGUI_BiIndexBase.cpp:32
MYGUI_ASSERT_RANGE_INSERT
#define MYGUI_ASSERT_RANGE_INSERT(index, size, owner)
Definition: MyGUI_Diagnostic.h:72
MyGUI::BiIndexBase::BiIndexBase
BiIndexBase()
Definition: MyGUI_BiIndexBase.cpp:28