Sync AMTL.
This commit is contained in:
parent
1c40d77b14
commit
da9debda67
@ -31,11 +31,14 @@
|
||||
#define _include_amtl_inline_list_h_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <assert.h>
|
||||
|
||||
namespace ke {
|
||||
|
||||
template <typename T> class InlineList;
|
||||
|
||||
// Objects can recursively inherit from InlineListNode in order to have
|
||||
// membership in an InlineList<T>.
|
||||
template <typename T>
|
||||
class InlineListNode
|
||||
{
|
||||
@ -43,14 +46,14 @@ class InlineListNode
|
||||
|
||||
public:
|
||||
InlineListNode()
|
||||
: next_(NULL),
|
||||
prev_(NULL)
|
||||
: next_(NULL),
|
||||
prev_(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
InlineListNode(InlineListNode *next, InlineListNode *prev)
|
||||
: next_(next),
|
||||
prev_(prev)
|
||||
: next_(next),
|
||||
prev_(prev)
|
||||
{
|
||||
}
|
||||
|
||||
@ -59,6 +62,14 @@ class InlineListNode
|
||||
InlineListNode *prev_;
|
||||
};
|
||||
|
||||
// An InlineList is a linked list that threads link pointers through objects,
|
||||
// rather than allocating node memory. A node can be in at most one list at
|
||||
// any time.
|
||||
//
|
||||
// Since InlineLists are designed to be very cheap, there is no requirement
|
||||
// that elements be removed from a list once the list is destructed. However,
|
||||
// for as long as the list is alive, all of its contained nodes must also
|
||||
// be alive.
|
||||
template <typename T>
|
||||
class InlineList
|
||||
{
|
||||
@ -66,12 +77,26 @@ class InlineList
|
||||
|
||||
Node head_;
|
||||
|
||||
// Work around a clang bug where we can't initialize with &head_ in the ctor.
|
||||
inline Node *head() {
|
||||
return &head_;
|
||||
}
|
||||
|
||||
public:
|
||||
InlineList()
|
||||
: head_(&head_, &head_)
|
||||
: head_(head(), head())
|
||||
{
|
||||
}
|
||||
|
||||
~InlineList()
|
||||
{
|
||||
#if !defined(NDEBUG)
|
||||
// Remove all items to clear their next/prev fields.
|
||||
while (begin() != end())
|
||||
remove(*begin());
|
||||
#endif
|
||||
}
|
||||
|
||||
public:
|
||||
class iterator
|
||||
{
|
||||
@ -86,7 +111,7 @@ class InlineList
|
||||
|
||||
iterator & operator ++() {
|
||||
iter_ = iter_->next;
|
||||
return *iter_;
|
||||
return *this;
|
||||
}
|
||||
iterator operator ++(int) {
|
||||
iterator old(*this);
|
||||
@ -105,14 +130,6 @@ class InlineList
|
||||
bool operator ==(const iterator &where) const {
|
||||
return iter_ == where.iter_;
|
||||
}
|
||||
iterator prev() const {
|
||||
iterator p(iter_->prev_);
|
||||
return p;
|
||||
}
|
||||
iterator next() const {
|
||||
iterator p(iter_->next_);
|
||||
return p;
|
||||
}
|
||||
};
|
||||
|
||||
iterator begin() {
|
||||
@ -126,9 +143,17 @@ class InlineList
|
||||
void remove(Node *t) {
|
||||
t->prev_->next_ = t->next_;
|
||||
t->next_->prev_ = t->prev_;
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
t->next_ = NULL;
|
||||
t->prev_ = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void insert(Node *t) {
|
||||
void append(Node *t) {
|
||||
assert(!t->next_);
|
||||
assert(!t->prev_);
|
||||
|
||||
t->prev_ = head_.prev_;
|
||||
t->next_ = &head_;
|
||||
head_.prev_->next_ = t;
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <am-allocator-policies.h>
|
||||
#include <am-utility.h>
|
||||
#include <am-moveable.h>
|
||||
|
||||
namespace ke {
|
||||
|
||||
@ -58,6 +59,10 @@ class LinkedList : public AllocPolicy
|
||||
: obj(o)
|
||||
{
|
||||
}
|
||||
Node(Moveable<T> o)
|
||||
: obj(o)
|
||||
{
|
||||
}
|
||||
|
||||
T obj;
|
||||
Node *next;
|
||||
@ -68,29 +73,28 @@ public:
|
||||
LinkedList(AllocPolicy = AllocPolicy())
|
||||
: length_(0)
|
||||
{
|
||||
head()->prev = head();
|
||||
head()->next = head();
|
||||
}
|
||||
~LinkedList() {
|
||||
clear();
|
||||
}
|
||||
|
||||
bool append(const T &obj) {
|
||||
Node *node = allocNode(obj);
|
||||
if (!node)
|
||||
return false;
|
||||
|
||||
node->prev = head()->prev;
|
||||
node->next = head();
|
||||
head()->prev->next = node;
|
||||
head()->prev = node;
|
||||
|
||||
length_++;
|
||||
return insertBefore(end(), obj) != end();
|
||||
}
|
||||
bool append(Moveable<T> obj) {
|
||||
return insertBefore(end(), obj) != end();
|
||||
}
|
||||
|
||||
bool prepend(const T &obj) {
|
||||
return insert(begin(), obj);
|
||||
return insertBefore(begin(), obj) != begin();
|
||||
}
|
||||
bool prepend(Moveable<T> obj) {
|
||||
return insertBefore(begin(), obj) != begin();
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
size_t length() const {
|
||||
return length_;
|
||||
}
|
||||
|
||||
@ -137,6 +141,13 @@ public:
|
||||
new (node) Node(obj);
|
||||
return node;
|
||||
}
|
||||
Node *allocNode(Moveable<T> obj) {
|
||||
Node *node = (Node *)this->malloc(sizeof(Node));
|
||||
if (!node)
|
||||
return NULL;
|
||||
new (node) Node(obj);
|
||||
return node;
|
||||
}
|
||||
|
||||
void freeNode(Node *node) {
|
||||
node->obj.~T();
|
||||
@ -221,29 +232,9 @@ public:
|
||||
Node *this_;
|
||||
};
|
||||
|
||||
public:
|
||||
iterator begin() const {
|
||||
return iterator(head()->next);
|
||||
}
|
||||
iterator end() const {
|
||||
return iterator(head());
|
||||
}
|
||||
iterator erase(iterator &where) {
|
||||
Node *pNode = where.this_;
|
||||
iterator iter(where);
|
||||
iter++;
|
||||
|
||||
pNode->prev->next = pNode->next;
|
||||
pNode->next->prev = pNode->prev;
|
||||
|
||||
freeNode(pNode);
|
||||
length_--;
|
||||
|
||||
return iter;
|
||||
}
|
||||
iterator insert(iterator where, const T &obj) {
|
||||
// Insert obj right before where
|
||||
Node *node = allocNode(obj);
|
||||
private:
|
||||
// Insert obj right before where.
|
||||
iterator insert(iterator where, Node *node) {
|
||||
if (!node)
|
||||
return where;
|
||||
|
||||
@ -259,6 +250,34 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
iterator begin() {
|
||||
return iterator(head()->next);
|
||||
}
|
||||
iterator end() {
|
||||
return iterator(head());
|
||||
}
|
||||
iterator erase(iterator where) {
|
||||
Node *pNode = where.this_;
|
||||
iterator iter(where);
|
||||
iter++;
|
||||
|
||||
pNode->prev->next = pNode->next;
|
||||
pNode->next->prev = pNode->prev;
|
||||
|
||||
freeNode(pNode);
|
||||
length_--;
|
||||
|
||||
return iter;
|
||||
}
|
||||
iterator insertBefore(iterator where, const T &obj) {
|
||||
return insert(where, allocNode(obj));
|
||||
}
|
||||
iterator insertBefore(iterator where, Moveable<T> obj) {
|
||||
return insert(where, allocNode(obj));
|
||||
}
|
||||
|
||||
public:
|
||||
// Removes one instance of |obj| from the list, if found.
|
||||
void remove(const T &obj) {
|
||||
for (iterator b = begin(); b != end(); b++) {
|
||||
if (*b == obj) {
|
||||
@ -269,7 +288,7 @@ public:
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
iterator find(const U &equ) const {
|
||||
iterator find(const U &equ) {
|
||||
for (iterator iter = begin(); iter != end(); iter++) {
|
||||
if (*iter == equ)
|
||||
return iter;
|
||||
|
@ -61,6 +61,13 @@ struct Moveable
|
||||
T &t_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
static inline Moveable<T>
|
||||
Move(T &t)
|
||||
{
|
||||
return Moveable<T>(t);
|
||||
}
|
||||
|
||||
} // namespace ke
|
||||
|
||||
#endif // _include_amtl_moveable_h_
|
||||
|
@ -81,6 +81,9 @@ class AString
|
||||
return *this;
|
||||
}
|
||||
|
||||
int compare(const char *str) const {
|
||||
return strcmp(chars(), str);
|
||||
}
|
||||
int compare(const AString &other) const {
|
||||
return strcmp(chars(), other.chars());
|
||||
}
|
||||
|
@ -43,24 +43,23 @@ class Vector : public AllocPolicy
|
||||
{
|
||||
public:
|
||||
Vector(AllocPolicy = AllocPolicy())
|
||||
: data_(NULL),
|
||||
nitems_(0),
|
||||
maxsize_(0)
|
||||
: data_(NULL),
|
||||
nitems_(0),
|
||||
maxsize_(0)
|
||||
{
|
||||
}
|
||||
|
||||
Vector(Moveable<Vector<T, AllocPolicy> > other) {
|
||||
data_ = other->data_;
|
||||
nitems_ = other->nitems_;
|
||||
maxsize_ = other->maxsize_;
|
||||
other->reset();
|
||||
}
|
||||
|
||||
~Vector() {
|
||||
zap();
|
||||
}
|
||||
|
||||
void steal(Vector &other) {
|
||||
zap();
|
||||
data_ = other.data_;
|
||||
nitems_ = other.nitems_;
|
||||
maxsize_ = other.maxsize_;
|
||||
other.reset();
|
||||
}
|
||||
|
||||
bool append(const T &item) {
|
||||
if (!growIfNeeded(1))
|
||||
return false;
|
||||
@ -68,11 +67,24 @@ class Vector : public AllocPolicy
|
||||
nitems_++;
|
||||
return true;
|
||||
}
|
||||
bool append(Moveable<T> item) {
|
||||
if (!growIfNeeded(1))
|
||||
return false;
|
||||
new (&data_[nitems_]) T(item);
|
||||
nitems_++;
|
||||
return true;
|
||||
}
|
||||
void infallibleAppend(const T &item) {
|
||||
assert(growIfNeeded(1));
|
||||
new (&data_[nitems_]) T(item);
|
||||
nitems_++;
|
||||
}
|
||||
void infallibleAppend(Moveable<T> item) {
|
||||
assert(growIfNeeded(1));
|
||||
new (&data_[nitems_]) T(item);
|
||||
nitems_++;
|
||||
}
|
||||
|
||||
T popCopy() {
|
||||
T t = at(length() - 1);
|
||||
pop();
|
||||
|
Loading…
Reference in New Issue
Block a user