# HG changeset patch # User David Anderson # Date 1377801928 25200 # Node ID 0ad3c734a69e8bd9203dcb59abef0d9d9625220f # Parent 0b7c5299f9fc499cb91bf33e696dfe68b21290c8 Sync AMTL. diff -r 0b7c5299f9fc -r 0ad3c734a69e public/amtl/am-inlinelist.h --- a/public/amtl/am-inlinelist.h Thu Aug 29 14:16:18 2013 -0400 +++ b/public/amtl/am-inlinelist.h Thu Aug 29 11:45:28 2013 -0700 @@ -31,11 +31,14 @@ #define _include_amtl_inline_list_h_ #include +#include namespace ke { template class InlineList; +// Objects can recursively inherit from InlineListNode in order to have +// membership in an InlineList. template class InlineListNode { @@ -43,14 +46,14 @@ 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 @@ 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 class InlineList { @@ -66,10 +77,24 @@ 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: @@ -86,7 +111,7 @@ iterator & operator ++() { iter_ = iter_->next; - return *iter_; + return *this; } iterator operator ++(int) { iterator old(*this); @@ -105,14 +130,6 @@ 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 @@ 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; diff -r 0b7c5299f9fc -r 0ad3c734a69e public/amtl/am-linkedlist.h --- a/public/amtl/am-linkedlist.h Thu Aug 29 14:16:18 2013 -0400 +++ b/public/amtl/am-linkedlist.h Thu Aug 29 11:45:28 2013 -0700 @@ -34,6 +34,7 @@ #include #include #include +#include namespace ke { @@ -58,6 +59,10 @@ : obj(o) { } + Node(Moveable o) + : obj(o) + { + } T obj; Node *next; @@ -68,29 +73,28 @@ 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 obj) { + return insertBefore(end(), obj) != end(); } bool prepend(const T &obj) { - return insert(begin(), obj); + return insertBefore(begin(), obj) != begin(); + } + bool prepend(Moveable obj) { + return insertBefore(begin(), obj) != begin(); } - size_t size() const { + size_t length() const { return length_; } @@ -137,6 +141,13 @@ new (node) Node(obj); return node; } + Node *allocNode(Moveable 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 @@ 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: + 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 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 @@ } template - iterator find(const U &equ) const { + iterator find(const U &equ) { for (iterator iter = begin(); iter != end(); iter++) { if (*iter == equ) return iter; diff -r 0b7c5299f9fc -r 0ad3c734a69e public/amtl/am-moveable.h --- a/public/amtl/am-moveable.h Thu Aug 29 14:16:18 2013 -0400 +++ b/public/amtl/am-moveable.h Thu Aug 29 11:45:28 2013 -0700 @@ -61,6 +61,13 @@ T &t_; }; +template +static inline Moveable +Move(T &t) +{ + return Moveable(t); +} + } // namespace ke #endif // _include_amtl_moveable_h_ diff -r 0b7c5299f9fc -r 0ad3c734a69e public/amtl/am-string.h --- a/public/amtl/am-string.h Thu Aug 29 14:16:18 2013 -0400 +++ b/public/amtl/am-string.h Thu Aug 29 11:45:28 2013 -0700 @@ -81,6 +81,9 @@ return *this; } + int compare(const char *str) const { + return strcmp(chars(), str); + } int compare(const AString &other) const { return strcmp(chars(), other.chars()); } diff -r 0b7c5299f9fc -r 0ad3c734a69e public/amtl/am-vector.h --- a/public/amtl/am-vector.h Thu Aug 29 14:16:18 2013 -0400 +++ b/public/amtl/am-vector.h Thu Aug 29 11:45:28 2013 -0700 @@ -43,25 +43,31 @@ { public: Vector(AllocPolicy = AllocPolicy()) - : data_(NULL), - nitems_(0), - maxsize_(0) + : data_(NULL), + nitems_(0), + maxsize_(0) { } + Vector(Moveable > 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; + new (&data_[nitems_]) T(item); + nitems_++; + return true; } - - bool append(const T &item) { + bool append(Moveable item) { if (!growIfNeeded(1)) return false; new (&data_[nitems_]) T(item); @@ -73,6 +79,12 @@ new (&data_[nitems_]) T(item); nitems_++; } + void infallibleAppend(Moveable item) { + assert(growIfNeeded(1)); + new (&data_[nitems_]) T(item); + nitems_++; + } + T popCopy() { T t = at(length() - 1); pop();