1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
// (c) 1994 Michael E. Stillman
#ifndef _queue_hh_
#define _queue_hh_
#include "newdelete.hpp"
#include <utility>
#include <cassert>
const int block_size = 128;
#define QUEUE(T) queue<T>
template <class T>
class queue;
template <class T>
class queue_block : public our_new_delete
{
friend class queue<T>;
T entries[block_size];
queue_block<T> *next;
queue_block() : next(NULL) {}
};
template <class T>
class queue : public our_new_delete
{
int ephemeral;
queue_block<T> *head;
int head_i;
queue_block<T> *tail;
int tail_i;
int len;
void copy(const queue<T> &q);
void obtain(const queue<T> &qq)
{
queue<T> &q = const_cast<queue<T> &>(qq);
if (q.ephemeral == 0)
copy(q);
else
{
ephemeral = 1;
std::swap(head, q.head);
std::swap(tail, q.tail);
std::swap(head_i, q.head_i);
std::swap(tail_i, q.tail_i);
std::swap(len, q.len);
}
}
void del_list()
{
while (head != NULL)
{
queue_block<T> *temp = head;
head = head->next;
delete temp;
}
}
public:
queue() : ephemeral(0), head(NULL), head_i(0), tail(NULL), tail_i(0), len(0)
{
}
queue(queue<T> &q) { obtain(q); }
~queue() { del_list(); }
void make_ephemeral() { ephemeral = 1; }
queue<T> &operator=(const queue<T> &q)
{
if (&q != this) obtain(q);
return *this;
}
void insert(const T &elem);
bool remove(T &elem);
void flush()
{
del_list();
tail = NULL;
head_i = tail_i = len = 0;
}
int length() const { return len; }
bool operator==(const queue<T> &) const { return false; }
bool operator!=(const queue<T> &) const { return true; }
};
template <class T>
void queue<T>::copy(const queue<T> &q)
{
assert(0);
if (q.len == 0)
{
while (head != NULL)
{
queue_block<T> *tmp = head;
head = head->next;
delete tmp;
}
head_i = tail_i = len = 0;
tail = NULL;
return;
}
}
template <class T>
void queue<T>::insert(const T &elem)
{
if (len == 0)
{
tail = head = new queue_block<T>;
tail_i = head_i = 0;
}
if (tail_i >= block_size)
{
tail = tail->next = new queue_block<T>;
tail_i = 0;
}
tail->entries[tail_i] = elem;
tail_i++;
len++;
}
template <class T>
bool queue<T>::remove(T &elem)
{
if (len == 0) return false;
elem = head->entries[head_i];
head_i++;
len--;
if (head == tail)
{
if (head_i == tail_i)
{
delete head;
head = NULL;
len = head_i = tail_i = 0;
}
}
else if (head_i >= block_size)
{
queue_block<T> *temp = head;
head = head->next;
delete temp;
head_i = 0;
}
return true;
}
#endif
// Local Variables:
// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
// indent-tabs-mode: nil
// End:
|