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 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
|
#pragma once
#include "Object.h"
#include "Handle.h"
#include "GcArray.h"
#include "StrBuf.h"
#include "Exception.h"
namespace storm {
STORM_PKG(core);
/**
* Base class for queues.
*/
class QueueBase : public Object {
STORM_CLASS;
public:
// Empty queue.
QueueBase(const Handle &type);
// Copy another queue.
QueueBase(const QueueBase &other);
// Deep copy.
virtual void STORM_FN deepCopy(CloneEnv *env);
// Reserve size.
void STORM_FN reserve(Nat count);
// Clear.
void STORM_FN clear();
// Number of elements.
inline Nat STORM_FN count() const { return data ? Nat(data->filled) : 0; }
// Any elements?
inline Bool STORM_FN any() const { return count() > 0; }
// Empty?
inline Bool STORM_FN empty() const { return count() == 0; }
// Get the top element.
void *CODECALL topRaw();
// Pop an element.
void STORM_FN pop();
// Push an element.
void CODECALL pushRaw(const void *elem);
// To string.
virtual void STORM_FN toS(StrBuf *to) const;
// Handle of the contained type.
const Handle &handle;
/**
* Base class for the iterator.
*/
class Iter {
STORM_VALUE;
public:
// Pointing to the end.
Iter();
// Pointing to the start.
Iter(QueueBase *owner, Nat index);
// Compare.
bool operator ==(const Iter &o) const;
bool operator !=(const Iter &o) const;
// Increase.
Iter &operator ++();
Iter operator ++(int z);
// Get raw element.
void *CODECALL getRaw() const;
// Get index.
inline Nat getIndex() const { return index; }
// Raw pre- and post increment.
Iter &CODECALL preIncRaw();
Iter CODECALL postIncRaw();
private:
// Queue we're pointing to.
QueueBase *owner;
// Index into the logical queue (i.e. relative to head).
Nat index;
// At end?
Bool atEnd() const;
};
// Begin and end.
Iter CODECALL beginRaw();
Iter CODECALL endRaw();
private:
// Data. We store 'count' in here.
GcArray<byte> *data;
// Head element.
Nat head;
// Get the pointer to an element.
inline void *ptr(GcArray<byte> *data, Nat id) const { return data->v + (id * handle.size); }
inline void *ptr(Nat id) const { return ptr(data, id); }
// Ensure data contains at least 'n' elements.
void ensure(Nat n);
// Step a variable around in the buffer.
inline void step(Nat &at) const {
if (++at == data->count)
at = 0;
}
};
// Declare the template in Storm.
STORM_TEMPLATE(Queue, createQueue);
/**
* Class used from C++.
*/
template <class T>
class Queue : public QueueBase {
STORM_SPECIAL;
public:
// Get the Storm type for this object.
static Type *stormType(Engine &e) {
return runtime::cppTemplate(e, QueueId, 1, StormInfo<T>::id());
}
// Empty queue.
Queue() : QueueBase(StormInfo<T>::handle(engine())) {
runtime::setVTable(this);
}
// Copy array.
Queue(const Queue &o) : QueueBase(o) {
runtime::setVTable(this);
}
// Get the top element.
T &top() {
return *(T *)topRaw();
}
// Push element.
void push(const T &item) {
pushRaw(&item);
}
// Push.
Queue<T> &operator <<(const T &item) {
pushRaw(&item);
return *this;
}
/**
* Iterator.
*/
class Iter : public QueueBase::Iter {
public:
Iter() : QueueBase::Iter() {}
Iter(Queue<T> *owner, Nat id) : QueueBase::Iter(owner, id) {}
T &operator *() const {
return *(T *)getRaw();
}
T &v() const {
return *(T *)getRaw();
}
T *operator ->() const {
return (T *)getRaw();
}
};
// Begin/end.
Iter begin() { return Iter(this, 0); }
Iter end() { return Iter(this, count); }
};
/**
* Custom error type for queues.
*/
class EXCEPTION_EXPORT QueueError : public Exception {
STORM_EXCEPTION;
public:
QueueError(const wchar *msg);
STORM_CTOR QueueError(Str *msg);
virtual void STORM_FN message(StrBuf *to) const;
private:
MAYBE(Str *) msg;
};
}
|