Sync AMTL.
This commit is contained in:
parent
1c40d77b14
commit
da9debda67
@ -31,11 +31,14 @@
|
|||||||
#define _include_amtl_inline_list_h_
|
#define _include_amtl_inline_list_h_
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
namespace ke {
|
namespace ke {
|
||||||
|
|
||||||
template <typename T> class InlineList;
|
template <typename T> class InlineList;
|
||||||
|
|
||||||
|
// Objects can recursively inherit from InlineListNode in order to have
|
||||||
|
// membership in an InlineList<T>.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class InlineListNode
|
class InlineListNode
|
||||||
{
|
{
|
||||||
@ -43,14 +46,14 @@ class InlineListNode
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
InlineListNode()
|
InlineListNode()
|
||||||
: next_(NULL),
|
: next_(NULL),
|
||||||
prev_(NULL)
|
prev_(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
InlineListNode(InlineListNode *next, InlineListNode *prev)
|
InlineListNode(InlineListNode *next, InlineListNode *prev)
|
||||||
: next_(next),
|
: next_(next),
|
||||||
prev_(prev)
|
prev_(prev)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,6 +62,14 @@ class InlineListNode
|
|||||||
InlineListNode *prev_;
|
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>
|
template <typename T>
|
||||||
class InlineList
|
class InlineList
|
||||||
{
|
{
|
||||||
@ -66,12 +77,26 @@ class InlineList
|
|||||||
|
|
||||||
Node head_;
|
Node head_;
|
||||||
|
|
||||||
|
// Work around a clang bug where we can't initialize with &head_ in the ctor.
|
||||||
|
inline Node *head() {
|
||||||
|
return &head_;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
InlineList()
|
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:
|
public:
|
||||||
class iterator
|
class iterator
|
||||||
{
|
{
|
||||||
@ -86,7 +111,7 @@ class InlineList
|
|||||||
|
|
||||||
iterator & operator ++() {
|
iterator & operator ++() {
|
||||||
iter_ = iter_->next;
|
iter_ = iter_->next;
|
||||||
return *iter_;
|
return *this;
|
||||||
}
|
}
|
||||||
iterator operator ++(int) {
|
iterator operator ++(int) {
|
||||||
iterator old(*this);
|
iterator old(*this);
|
||||||
@ -105,14 +130,6 @@ class InlineList
|
|||||||
bool operator ==(const iterator &where) const {
|
bool operator ==(const iterator &where) const {
|
||||||
return iter_ == where.iter_;
|
return iter_ == where.iter_;
|
||||||
}
|
}
|
||||||
iterator prev() const {
|
|
||||||
iterator p(iter_->prev_);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
iterator next() const {
|
|
||||||
iterator p(iter_->next_);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
iterator begin() {
|
iterator begin() {
|
||||||
@ -126,9 +143,17 @@ class InlineList
|
|||||||
void remove(Node *t) {
|
void remove(Node *t) {
|
||||||
t->prev_->next_ = t->next_;
|
t->prev_->next_ = t->next_;
|
||||||
t->next_->prev_ = t->prev_;
|
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->prev_ = head_.prev_;
|
||||||
t->next_ = &head_;
|
t->next_ = &head_;
|
||||||
head_.prev_->next_ = t;
|
head_.prev_->next_ = t;
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <am-allocator-policies.h>
|
#include <am-allocator-policies.h>
|
||||||
#include <am-utility.h>
|
#include <am-utility.h>
|
||||||
|
#include <am-moveable.h>
|
||||||
|
|
||||||
namespace ke {
|
namespace ke {
|
||||||
|
|
||||||
@ -58,6 +59,10 @@ class LinkedList : public AllocPolicy
|
|||||||
: obj(o)
|
: obj(o)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
Node(Moveable<T> o)
|
||||||
|
: obj(o)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
T obj;
|
T obj;
|
||||||
Node *next;
|
Node *next;
|
||||||
@ -68,29 +73,28 @@ public:
|
|||||||
LinkedList(AllocPolicy = AllocPolicy())
|
LinkedList(AllocPolicy = AllocPolicy())
|
||||||
: length_(0)
|
: length_(0)
|
||||||
{
|
{
|
||||||
|
head()->prev = head();
|
||||||
|
head()->next = head();
|
||||||
}
|
}
|
||||||
~LinkedList() {
|
~LinkedList() {
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool append(const T &obj) {
|
bool append(const T &obj) {
|
||||||
Node *node = allocNode(obj);
|
return insertBefore(end(), obj) != end();
|
||||||
if (!node)
|
}
|
||||||
return false;
|
bool append(Moveable<T> obj) {
|
||||||
|
return insertBefore(end(), obj) != end();
|
||||||
node->prev = head()->prev;
|
|
||||||
node->next = head();
|
|
||||||
head()->prev->next = node;
|
|
||||||
head()->prev = node;
|
|
||||||
|
|
||||||
length_++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool prepend(const T &obj) {
|
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_;
|
return length_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,6 +141,13 @@ public:
|
|||||||
new (node) Node(obj);
|
new (node) Node(obj);
|
||||||
return node;
|
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) {
|
void freeNode(Node *node) {
|
||||||
node->obj.~T();
|
node->obj.~T();
|
||||||
@ -221,29 +232,9 @@ public:
|
|||||||
Node *this_;
|
Node *this_;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
private:
|
||||||
iterator begin() const {
|
// Insert obj right before where.
|
||||||
return iterator(head()->next);
|
iterator insert(iterator where, Node *node) {
|
||||||
}
|
|
||||||
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);
|
|
||||||
if (!node)
|
if (!node)
|
||||||
return where;
|
return where;
|
||||||
|
|
||||||
@ -259,6 +250,34 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
void remove(const T &obj) {
|
||||||
for (iterator b = begin(); b != end(); b++) {
|
for (iterator b = begin(); b != end(); b++) {
|
||||||
if (*b == obj) {
|
if (*b == obj) {
|
||||||
@ -269,7 +288,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename U>
|
template <typename U>
|
||||||
iterator find(const U &equ) const {
|
iterator find(const U &equ) {
|
||||||
for (iterator iter = begin(); iter != end(); iter++) {
|
for (iterator iter = begin(); iter != end(); iter++) {
|
||||||
if (*iter == equ)
|
if (*iter == equ)
|
||||||
return iter;
|
return iter;
|
||||||
|
@ -61,6 +61,13 @@ struct Moveable
|
|||||||
T &t_;
|
T &t_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static inline Moveable<T>
|
||||||
|
Move(T &t)
|
||||||
|
{
|
||||||
|
return Moveable<T>(t);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ke
|
} // namespace ke
|
||||||
|
|
||||||
#endif // _include_amtl_moveable_h_
|
#endif // _include_amtl_moveable_h_
|
||||||
|
@ -81,6 +81,9 @@ class AString
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int compare(const char *str) const {
|
||||||
|
return strcmp(chars(), str);
|
||||||
|
}
|
||||||
int compare(const AString &other) const {
|
int compare(const AString &other) const {
|
||||||
return strcmp(chars(), other.chars());
|
return strcmp(chars(), other.chars());
|
||||||
}
|
}
|
||||||
|
@ -43,24 +43,23 @@ class Vector : public AllocPolicy
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Vector(AllocPolicy = AllocPolicy())
|
Vector(AllocPolicy = AllocPolicy())
|
||||||
: data_(NULL),
|
: data_(NULL),
|
||||||
nitems_(0),
|
nitems_(0),
|
||||||
maxsize_(0)
|
maxsize_(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector(Moveable<Vector<T, AllocPolicy> > other) {
|
||||||
|
data_ = other->data_;
|
||||||
|
nitems_ = other->nitems_;
|
||||||
|
maxsize_ = other->maxsize_;
|
||||||
|
other->reset();
|
||||||
|
}
|
||||||
|
|
||||||
~Vector() {
|
~Vector() {
|
||||||
zap();
|
zap();
|
||||||
}
|
}
|
||||||
|
|
||||||
void steal(Vector &other) {
|
|
||||||
zap();
|
|
||||||
data_ = other.data_;
|
|
||||||
nitems_ = other.nitems_;
|
|
||||||
maxsize_ = other.maxsize_;
|
|
||||||
other.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool append(const T &item) {
|
bool append(const T &item) {
|
||||||
if (!growIfNeeded(1))
|
if (!growIfNeeded(1))
|
||||||
return false;
|
return false;
|
||||||
@ -68,11 +67,24 @@ class Vector : public AllocPolicy
|
|||||||
nitems_++;
|
nitems_++;
|
||||||
return true;
|
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) {
|
void infallibleAppend(const T &item) {
|
||||||
assert(growIfNeeded(1));
|
assert(growIfNeeded(1));
|
||||||
new (&data_[nitems_]) T(item);
|
new (&data_[nitems_]) T(item);
|
||||||
nitems_++;
|
nitems_++;
|
||||||
}
|
}
|
||||||
|
void infallibleAppend(Moveable<T> item) {
|
||||||
|
assert(growIfNeeded(1));
|
||||||
|
new (&data_[nitems_]) T(item);
|
||||||
|
nitems_++;
|
||||||
|
}
|
||||||
|
|
||||||
T popCopy() {
|
T popCopy() {
|
||||||
T t = at(length() - 1);
|
T t = at(length() - 1);
|
||||||
pop();
|
pop();
|
||||||
|
Loading…
Reference in New Issue
Block a user