Sync AMTL.

This commit is contained in:
David Anderson 2013-08-29 11:45:28 -07:00
parent 1c40d77b14
commit da9debda67
5 changed files with 128 additions and 62 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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_

View File

@ -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());
}

View File

@ -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();