Files
scummvm/engines/ags/lib/std/list.h
T
Thierry Crozat 9144ec7131 AGS: Add sanity check on iterators in implementation of std::list::splice
In particular the SpriteCache class can call this function with both
iterators pointing to the same item (when trying to move an item to
the start of thr MRU list, and it is already the first item).
2022-06-18 22:20:40 +01:00

93 lines
2.4 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef AGS_STD_LIST_H
#define AGS_STD_LIST_H
#include "common/list.h"
namespace AGS3 {
namespace std {
template<class T>
class list : public Common::List<T> {
public:
struct reverse_iterator {
private:
typename Common::List<T>::iterator _it;
public:
reverse_iterator(typename Common::List<T>::iterator it) : _it(it) {
}
reverse_iterator() {
}
T operator*() const {
return *_it;
}
reverse_iterator &operator++() {
--_it;
return *this;
}
bool operator==(const reverse_iterator &rhs) {
return _it == rhs._it;
}
bool operator!=(const reverse_iterator &rhs) {
return _it != rhs._it;
}
};
public:
typename Common::List<T>::iterator insert(typename Common::List<T>::iterator pos,
const T &element) {
Common::List<T>::insert(pos, element);
return --pos;
}
reverse_iterator rbegin() {
return reverse_iterator(Common::List<T>::reverse_begin());
}
reverse_iterator rend() {
return reverse_iterator(Common::List<T>::end());
}
void splice(typename Common::List<T>::iterator pos, list<T>& /*other*/, typename Common::List<T>::iterator it ) {
// We insert it before pos in this list
typename Common::List<T>::NodeBase *n = it._node;
typename Common::List<T>::NodeBase *nPos = pos._node;
if (n == nullptr || nPos == nullptr || n == nPos || n->_next == nPos)
return;
// Remove from current position
n->_prev->_next = n->_next;
n->_next->_prev = n->_prev;
// Insert in new position
n->_next = nPos;
n->_prev = nPos->_prev;
n->_prev->_next = n;
n->_next->_prev = n;
}
};
} // namespace std
} // namespace AGS3
#endif