2
* Inkscape::Util::ListContainer - encapsulates lists as STL containers,
3
* providing fast appending
6
* MenTaLguY <mental@rydia.net>
8
* Copyright (C) 2005 MenTaLguY
10
* Released under GNU GPL, read the file 'COPYING' for more information
13
#ifndef SEEN_INKSCAPE_UTIL_LIST_CONTAINER_H
14
#define SEEN_INKSCAPE_UTIL_LIST_CONTAINER_H
17
#include "util/list.h"
26
/* default constructible */
30
ListContainer(ListContainer const &other) {
33
ListContainer &operator=(ListContainer const &other) {
35
for ( const_iterator iter = other.begin() ; iter ; ++iter ) {
40
void swap(ListContainer<T> &other) {
41
std::swap(other._head, _head);
42
std::swap(other._tail, _tail);
45
/* equality comparable */
46
bool operator==(ListContainer const &other) const {
47
const_iterator iter = _head;
48
const_iterator other_iter = other._head;
49
while ( iter && other_iter ) {
50
if (!( *iter == *other_iter )) {
56
return !iter && !other_iter;
58
bool operator!=(ListContainer const &other) const {
59
return !operator==(other);
62
/* lessthan comparable */
63
bool operator<(ListContainer const &other) const {
64
const_iterator iter = _head;
65
const_iterator other_iter = other._head;
66
while ( iter && other_iter ) {
67
if ( *iter < *other_iter ) {
69
} else if ( *other_iter < *iter ) {
75
return bool(other_iter);
77
bool operator>=(ListContainer const &other) const {
78
return !operator<(other);
82
typedef typename List<T>::value_type value_type;
83
typedef List<T> iterator;
84
typedef List<T const> const_iterator;
85
typedef typename List<T>::reference reference;
86
typedef typename List<T>::const_reference const_reference;
87
typedef typename List<T>::pointer pointer;
88
typedef typename List<T>::difference_type difference_type;
89
typedef std::size_t size_type;
91
iterator begin() { return _head; }
92
const_iterator begin() const { return _head; }
93
iterator end() { return iterator(); }
94
const_iterator end() const { return const_iterator(); }
95
size_type size() const {
97
for ( iterator iter = _head ; iter ; ++iter ) {
102
size_type max_size() const {
103
return std::numeric_limits<std::size_t>::max();
105
bool empty() const { return !_head; }
108
ListContainer(size_type count, const_reference value) {
109
for ( ; count ; --count ) {
113
ListContainer(size_type count) {
114
value_type default_value;
115
for ( ; count ; --count ) {
116
push_back(default_value);
119
template <typename ForwardIterator>
120
ListContainer(ForwardIterator i, ForwardIterator j) {
121
for ( ; i != j ; ++i ) {
126
reference front() { return *_head; }
127
const_reference front() const { return *_head; }
129
iterator insert(const_iterator position, const_reference value) {
131
if ( position != _head ) {
132
MutableList<T> added(value);
133
MutableList<T> before=_before(position);
134
set_rest(added, rest(before));
135
set_rest(before, added);
146
void insert(const_iterator position, size_type count, const_reference value)
148
_insert_from_temp(position, ListContainer(count, value));
150
template <typename ForwardIterator>
151
void insert(const_iterator position, ForwardIterator i, ForwardIterator j) {
152
_insert_from_temp(position, ListContainer(i, j));
154
void erase(const_iterator position) {
155
erase(position, rest(position));
157
void erase(const_iterator i, const_iterator j) {
159
_head = static_cast<MutableList<T> &>(j);
160
if ( !j || !rest(j) ) {
164
MutableList<T> before=_before(i);
166
set_rest(before, static_cast<MutableList<T> &>(j));
168
set_rest(before, MutableList<T>());
174
_head = _tail = MutableList<T>();
176
void resize(size_type size, const_reference fill) {
177
MutableList<T> before;
179
for ( iter = _head ; iter && size ; ++iter ) {
184
ListContainer temp(size, fill);
189
set_rest(_tail, temp._head);
194
set_rest(before, MutableList<T>());
197
_head = _tail = MutableList<T>();
201
void resize(size_type size) {
202
resize(size, value_type());
205
/* front insertion sequence */
206
void push_front(const_reference value) {
208
_head = cons(value, _head);
210
_head = _tail = MutableList<T>(value);
222
/* back insertion sequence */
223
reference back() { return *_tail; }
224
const_reference back() const { return *_tail; }
225
void push_back(const_reference value) {
227
MutableList<T> added(value);
228
set_rest(_tail, added);
231
_head = _tail = MutableList<T>(value);
234
// we're not required to provide pop_back if we can't
235
// implement it efficiently
238
MutableList<T> detatchList() {
239
MutableList<T> list=_head;
240
_head = _tail = MutableList<T>();
243
iterator insert_after(const_iterator pos, const_reference value) {
244
MutableList<T> added(value);
246
MutableList<T> before=static_cast<MutableList<T> &>(pos);
247
set_rest(added, rest(before));
248
set_rest(before, added);
249
if ( _tail == before ) {
256
void insert_after(const_iterator position, size_type count,
257
const_reference value)
259
_insert_after_from_temp(position, ListContainer(count, value));
261
template <typename ForwardIterator>
262
void insert_after(const_iterator position,
263
ForwardIterator i, ForwardIterator j)
265
_insert_after_from_temp(position, ListContainer(i, j));
267
void erase_after(const_iterator position) {
271
MutableList<T> before=static_cast<MutableList<T> &>(position);
272
MutableList<T> removed=rest(before);
273
set_rest(before, rest(removed));
274
if ( removed == _tail ) {
281
MutableList<T> _head;
282
MutableList<T> _tail;
284
MutableList<T> _before(const_iterator position) {
285
for ( MutableList<T> iter = _head ; iter ; ++iter ) {
286
if ( rest(iter) == position ) {
290
return MutableList<T>();
292
void _insert_from_temp(const_iterator pos, ListContainer const &temp) {
296
if (empty()) { /* if empty, just take the whole thing */
300
if ( pos == _head ) { /* prepend */
301
set_rest(temp._tail, _head);
303
} else { /* insert somewhere in the middle */
304
MutableList<T> before=_before(pos);
305
set_rest(temp._tail, static_cast<MutableList<T> &>(pos));
306
set_rest(before, temp._head);
308
} else { /* append */
309
set_rest(_tail, temp._head);
313
void _insert_after_from_temp(const_iterator pos,
314
ListContainer const &temp)
319
if (empty()) { /* if empty, just take the whole thing */
323
if ( pos == _tail ) { /* append */
324
set_rest(_tail, temp._head);
326
} else { /* insert somewhere in the middle */
327
MutableList<T> before=static_cast<MutableList<T> &>(pos);
328
set_rest(temp._tail, rest(before));
329
set_rest(before, temp._head);
331
} else { /* prepend */
332
set_rest(temp._tail, _head);
346
c-file-style:"stroustrup"
347
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
352
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :