PageRenderTime 15ms CodeModel.GetById 2ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/src/rt/util/indexed_list.h

http://github.com/jruderman/rust
C Header | 97 lines | 72 code | 10 blank | 15 comment | 5 complexity | 8fdbf74948691da6855db4540cdadd64 MD5 | raw file
 1// -*- c++ -*-
 2#ifndef INDEXED_LIST_H
 3#define INDEXED_LIST_H
 4
 5#include <assert.h>
 6#include "array_list.h"
 7
 8class indexed_list_object {
 9public:
10    int32_t list_index;
11};
12
13template<typename T>
14class indexed_list_element : public indexed_list_object {
15public:
16    T value;
17    indexed_list_element(T value) : value(value) {
18    }
19};
20
21/**
22 * An array list of objects that are aware of their position in the list.
23 * Normally, objects in this list should derive from the base class
24 * "indexed_list_object" however because of nasty Rust compiler dependencies
25 * on the layout of runtime objects we cannot always derive from this
26 * base class, so instead we just enforce the informal protocol that any
27 * object inserted in this list must define a "int32_t list_index" member.
28 */
29template<typename T> class indexed_list {
30    array_list<T*> list;
31public:
32    virtual int32_t append(T *value);
33    virtual bool pop(T **value);
34    /**
35     * Same as pop(), except that it returns NULL if the list is empty.
36     */
37    virtual T* pop_value();
38    virtual size_t length() {
39        return list.size();
40    }
41    virtual bool is_empty() {
42        return list.is_empty();
43    }
44    virtual int32_t remove(T* value);
45    virtual T * operator[](int32_t index);
46    virtual ~indexed_list() {}
47};
48
49template<typename T> int32_t
50indexed_list<T>::append(T *value) {
51    value->list_index = list.push(value);
52    return value->list_index;
53}
54
55/**
56 * Swap delete the last object in the list with the specified object.
57 */
58template<typename T> int32_t
59indexed_list<T>::remove(T *value) {
60    assert (value->list_index >= 0);
61    assert (value->list_index < (int32_t)list.size());
62    int32_t removeIndex = value->list_index;
63    T *last = 0;
64    list.pop(&last);
65    if (last->list_index == removeIndex) {
66        last->list_index = -1;
67        return removeIndex;
68    } else {
69        value->list_index = -1;
70        list[removeIndex] = last;
71        last->list_index = removeIndex;
72        return removeIndex;
73    }
74}
75
76template<typename T> bool
77indexed_list<T>::pop(T **value) {
78    return list.pop(value);
79}
80
81template<typename T> T*
82indexed_list<T>::pop_value() {
83    T *value = NULL;
84    if (list.pop(&value)) {
85        return value;
86    }
87    return NULL;
88}
89
90template <typename T> T *
91indexed_list<T>::operator[](int32_t index) {
92    T *value = list[index];
93    assert(value->list_index == index);
94    return value;
95}
96
97#endif /* INDEXED_LIST_H */