MyGUI_BiIndexBase.cpp
Go to the documentation of this file.
/*
* This source file is part of MyGUI. For the latest info, see http://mygui.info/
* Distributed under the MIT License
* (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
*/
#include "MyGUI_Precompiled.h"
#include "MyGUI_BiIndexBase.h"
namespace MyGUI
{
size_t BiIndexBase::getIndexCount() const
{
return mIndexFace.size();
}
size_t BiIndexBase::insertItemAt(size_t _index)
{
#if MYGUI_DEBUG_MODE == 1
MYGUI_ASSERT_RANGE_INSERT(_index, mIndexFace.size(), "BiIndexBase::insertItemAt");
checkIndexes();
#endif
if (_index == MyGUI::ITEM_NONE)
_index = mIndexFace.size();
size_t index;
if (_index == mIndexFace.size())
{
// для вставки айтема
index = mIndexFace.size();
mIndexFace.push_back(_index);
mIndexBack.push_back(_index);
}
else
{
// для вставки айтема
index = mIndexFace[_index];
size_t count = mIndexFace.size();
for (size_t pos = 0; pos < count; ++pos)
{
if (mIndexFace[pos] >= index)
mIndexFace[pos]++;
}
mIndexFace.insert(mIndexFace.begin() + _index, index);
count++;
mIndexBack.push_back(0);
for (size_t pos = 0; pos < count; ++pos)
{
mIndexBack[mIndexFace[pos]] = pos;
}
}
#if MYGUI_DEBUG_MODE == 1
checkIndexes();
#endif
return index;
}
size_t BiIndexBase::removeItemAt(size_t _index)
{
#if MYGUI_DEBUG_MODE == 1
MYGUI_ASSERT_RANGE(_index, mIndexFace.size(), "BiIndexBase::removeItemAt");
checkIndexes();
#endif
// для удаления айтема
size_t index = mIndexFace[_index];
mIndexFace.erase(mIndexFace.begin() + _index);
mIndexBack.pop_back();
size_t count = mIndexFace.size();
for (size_t pos = 0; pos < count; ++pos)
{
if (mIndexFace[pos] > index)
mIndexFace[pos]--;
mIndexBack[mIndexFace[pos]] = pos;
}
#if MYGUI_DEBUG_MODE == 1
checkIndexes();
#endif
return index;
}
void BiIndexBase::removeAllItems()
{
mIndexFace.clear();
mIndexBack.clear();
}
// на входе индексы пользователя, на выходе реальные индексы
size_t BiIndexBase::convertToBack(size_t _index) const
{
#if MYGUI_DEBUG_MODE == 1
MYGUI_ASSERT_RANGE_AND_NONE(_index, mIndexFace.size(), "BiIndexBase::convertToBack");
#endif
return _index == ITEM_NONE ? ITEM_NONE : mIndexFace[_index];
}
// на входе индексы реальные, на выходе, то что видит пользователь
size_t BiIndexBase::convertToFace(size_t _index) const
{
#if MYGUI_DEBUG_MODE == 1
MYGUI_ASSERT_RANGE_AND_NONE(_index, mIndexFace.size(), "BiIndexBase::convertToFace");
#endif
return _index == ITEM_NONE ? ITEM_NONE : mIndexBack[_index];
}
// меняет местами два индекса, индексы со стороны пользователя
void BiIndexBase::swapItemsFaceAt(size_t _index1, size_t _index2)
{
#if MYGUI_DEBUG_MODE == 1
MYGUI_ASSERT_RANGE(_index1, mIndexFace.size(), "BiIndexBase::swapItemsFaceAt");
MYGUI_ASSERT_RANGE(_index2, mIndexFace.size(), "BiIndexBase::swapItemsFaceAt");
#endif
std::swap(mIndexFace[_index1], mIndexFace[_index2]);
std::swap(mIndexBack[mIndexFace[_index1]], mIndexBack[mIndexFace[_index2]]);
}
// меняет местами два индекса, индексы со сторонны данных
void BiIndexBase::swapItemsBackAt(size_t _index1, size_t _index2)
{
#if MYGUI_DEBUG_MODE == 1
MYGUI_ASSERT_RANGE(_index1, mIndexFace.size(), "BiIndexBase::swapItemsBackAt");
MYGUI_ASSERT_RANGE(_index2, mIndexFace.size(), "BiIndexBase::swapItemsBackAt");
#endif
std::swap(mIndexBack[_index1], mIndexBack[_index2]);
std::swap(mIndexFace[mIndexBack[_index1]], mIndexFace[mIndexBack[_index2]]);
}
void BiIndexBase::checkIndexes()
{
assert(mIndexFace.size() == mIndexBack.size());
// check that index is unique
std::vector<bool> vec;
size_t count = mIndexFace.size();
vec.reserve(count);
for (size_t pos = 0; pos < count; ++pos)
vec.push_back(false);
for (size_t pos = 0; pos < count; ++pos)
{
size_t index = mIndexBack[pos];
MYGUI_ASSERT(index < count, "Invalid index");
index = mIndexFace[pos];
MYGUI_ASSERT(index < count, "Invalid index");
MYGUI_ASSERT(!vec[index], "Invalid index");
vec[index] = true;
}
// check for index cross-reference
for (size_t pos = 0; pos < count; ++pos)
{
size_t index = mIndexFace[pos];
MYGUI_ASSERT(mIndexBack[index] == pos, "Invalid index: cross-reference");
}
}
} // namespace MyGUI
MyGUI_BiIndexBase.h
MYGUI_ASSERT
#define MYGUI_ASSERT(exp, dest)
Definition MyGUI_Diagnostic.h:31
MYGUI_ASSERT_RANGE_INSERT
#define MYGUI_ASSERT_RANGE_INSERT(index, size, owner)
Definition MyGUI_Diagnostic.h:50
MYGUI_ASSERT_RANGE
#define MYGUI_ASSERT_RANGE(index, size, owner)
Definition MyGUI_Diagnostic.h:44
MYGUI_ASSERT_RANGE_AND_NONE
#define MYGUI_ASSERT_RANGE_AND_NONE(index, size, owner)
Definition MyGUI_Diagnostic.h:46
MyGUI_Precompiled.h
MyGUI::BiIndexBase::checkIndexes
void checkIndexes()
Definition MyGUI_BiIndexBase.cpp:142
MyGUI::BiIndexBase::removeAllItems
void removeAllItems()
Definition MyGUI_BiIndexBase.cpp:94
MyGUI::BiIndexBase::swapItemsBackAt
void swapItemsBackAt(size_t _index1, size_t _index2)
Definition MyGUI_BiIndexBase.cpp:131
MyGUI::BiIndexBase::removeItemAt
size_t removeItemAt(size_t _index)
Definition MyGUI_BiIndexBase.cpp:66
MyGUI::BiIndexBase::insertItemAt
size_t insertItemAt(size_t _index)
Definition MyGUI_BiIndexBase.cpp:18
MyGUI::BiIndexBase::convertToBack
size_t convertToBack(size_t _index) const
Definition MyGUI_BiIndexBase.cpp:101
MyGUI::BiIndexBase::convertToFace
size_t convertToFace(size_t _index) const
Definition MyGUI_BiIndexBase.cpp:110
MyGUI::BiIndexBase::getIndexCount
size_t getIndexCount() const
Definition MyGUI_BiIndexBase.cpp:13
MyGUI::BiIndexBase::swapItemsFaceAt
void swapItemsFaceAt(size_t _index1, size_t _index2)
Definition MyGUI_BiIndexBase.cpp:119
MyGUI
Definition MyGUI_ActionController.h:15
MyGUI::ITEM_NONE
constexpr size_t ITEM_NONE
Definition MyGUI_Macros.h:19