Sync AMTL.
authorDavid Anderson <dvander@alliedmods.net>
Thu Aug 29 11:45:28 2013 -0700 (2013-08-29)
changeset 40990ad3c734a69e
parent 4098 0b7c5299f9fc
child 4100 10bc39fcb710
Sync AMTL.
public/amtl/am-inlinelist.h
public/amtl/am-linkedlist.h
public/amtl/am-moveable.h
public/amtl/am-string.h
public/amtl/am-vector.h
     1.1 --- a/public/amtl/am-inlinelist.h	Thu Aug 29 14:16:18 2013 -0400
     1.2 +++ b/public/amtl/am-inlinelist.h	Thu Aug 29 11:45:28 2013 -0700
     1.3 @@ -31,11 +31,14 @@
     1.4  #define _include_amtl_inline_list_h_
     1.5  
     1.6  #include <stddef.h>
     1.7 +#include <assert.h>
     1.8  
     1.9  namespace ke {
    1.10  
    1.11  template <typename T> class InlineList;
    1.12  
    1.13 +// Objects can recursively inherit from InlineListNode in order to have
    1.14 +// membership in an InlineList<T>.
    1.15  template <typename T>
    1.16  class InlineListNode
    1.17  {
    1.18 @@ -43,14 +46,14 @@
    1.19  
    1.20    public:
    1.21    InlineListNode()
    1.22 -    : next_(NULL),
    1.23 -    prev_(NULL)
    1.24 +   : next_(NULL),
    1.25 +     prev_(NULL)
    1.26    {
    1.27    }
    1.28  
    1.29    InlineListNode(InlineListNode *next, InlineListNode *prev)
    1.30 -    : next_(next),
    1.31 -    prev_(prev)
    1.32 +   : next_(next),
    1.33 +     prev_(prev)
    1.34    {
    1.35    }
    1.36  
    1.37 @@ -59,6 +62,14 @@
    1.38    InlineListNode *prev_;
    1.39  };
    1.40  
    1.41 +// An InlineList is a linked list that threads link pointers through objects,
    1.42 +// rather than allocating node memory. A node can be in at most one list at
    1.43 +// any time.
    1.44 +//
    1.45 +// Since InlineLists are designed to be very cheap, there is no requirement
    1.46 +// that elements be removed from a list once the list is destructed. However,
    1.47 +// for as long as the list is alive, all of its contained nodes must also
    1.48 +// be alive.
    1.49  template <typename T>
    1.50  class InlineList
    1.51  {
    1.52 @@ -66,10 +77,24 @@
    1.53  
    1.54    Node head_;
    1.55  
    1.56 +  // Work around a clang bug where we can't initialize with &head_ in the ctor.
    1.57 +  inline Node *head() {
    1.58 +    return &head_;
    1.59 +  }
    1.60 +
    1.61   public:
    1.62    InlineList()
    1.63 -    : head_(&head_, &head_)
    1.64 +    : head_(head(), head())
    1.65 +  {
    1.66 +  }
    1.67 +
    1.68 +  ~InlineList()
    1.69    {
    1.70 +#if !defined(NDEBUG)
    1.71 +    // Remove all items to clear their next/prev fields.
    1.72 +    while (begin() != end())
    1.73 +      remove(*begin());
    1.74 +#endif
    1.75    }
    1.76  
    1.77   public:
    1.78 @@ -86,7 +111,7 @@
    1.79  
    1.80      iterator & operator ++() {
    1.81        iter_ = iter_->next;
    1.82 -      return *iter_;
    1.83 +      return *this;
    1.84      }
    1.85      iterator operator ++(int) {
    1.86        iterator old(*this);
    1.87 @@ -105,14 +130,6 @@
    1.88      bool operator ==(const iterator &where) const {
    1.89        return iter_ == where.iter_;
    1.90      }
    1.91 -    iterator prev() const {
    1.92 -      iterator p(iter_->prev_);
    1.93 -      return p;
    1.94 -    }
    1.95 -    iterator next() const {
    1.96 -      iterator p(iter_->next_);
    1.97 -      return p;
    1.98 -    }
    1.99    };
   1.100  
   1.101    iterator begin() {
   1.102 @@ -126,9 +143,17 @@
   1.103    void remove(Node *t) {
   1.104      t->prev_->next_ = t->next_;
   1.105      t->next_->prev_ = t->prev_;
   1.106 +
   1.107 +#if !defined(NDEBUG)
   1.108 +    t->next_ = NULL;
   1.109 +    t->prev_ = NULL;
   1.110 +#endif
   1.111    }
   1.112  
   1.113 -  void insert(Node *t) {
   1.114 +  void append(Node *t) {
   1.115 +    assert(!t->next_);
   1.116 +    assert(!t->prev_);
   1.117 +
   1.118      t->prev_ = head_.prev_;
   1.119      t->next_ = &head_;
   1.120      head_.prev_->next_ = t;
     2.1 --- a/public/amtl/am-linkedlist.h	Thu Aug 29 14:16:18 2013 -0400
     2.2 +++ b/public/amtl/am-linkedlist.h	Thu Aug 29 11:45:28 2013 -0700
     2.3 @@ -34,6 +34,7 @@
     2.4  #include <stdlib.h>
     2.5  #include <am-allocator-policies.h>
     2.6  #include <am-utility.h>
     2.7 +#include <am-moveable.h>
     2.8  
     2.9  namespace ke {
    2.10  
    2.11 @@ -58,6 +59,10 @@
    2.12       : obj(o)
    2.13      {
    2.14      }
    2.15 +    Node(Moveable<T> o)
    2.16 +     : obj(o)
    2.17 +    {
    2.18 +    }
    2.19  
    2.20      T obj;
    2.21      Node *next;
    2.22 @@ -68,29 +73,28 @@
    2.23    LinkedList(AllocPolicy = AllocPolicy())
    2.24     : length_(0)
    2.25    {
    2.26 +    head()->prev = head();
    2.27 +    head()->next = head();
    2.28    }
    2.29    ~LinkedList() {
    2.30      clear();
    2.31    }
    2.32  
    2.33    bool append(const T &obj) {
    2.34 -    Node *node = allocNode(obj);
    2.35 -    if (!node)
    2.36 -      return false;
    2.37 -
    2.38 -    node->prev = head()->prev;
    2.39 -    node->next = head();
    2.40 -    head()->prev->next = node;
    2.41 -    head()->prev = node;
    2.42 -
    2.43 -    length_++;
    2.44 +    return insertBefore(end(), obj) != end();
    2.45 +  }
    2.46 +  bool append(Moveable<T> obj) {
    2.47 +    return insertBefore(end(), obj) != end();
    2.48    }
    2.49  
    2.50    bool prepend(const T &obj) {
    2.51 -    return insert(begin(), obj);
    2.52 +    return insertBefore(begin(), obj) != begin();
    2.53 +  }
    2.54 +  bool prepend(Moveable<T> obj) {
    2.55 +    return insertBefore(begin(), obj) != begin();
    2.56    }
    2.57  
    2.58 -  size_t size() const {
    2.59 +  size_t length() const {
    2.60      return length_;
    2.61    }
    2.62  
    2.63 @@ -137,6 +141,13 @@
    2.64      new (node) Node(obj);
    2.65      return node;
    2.66    }
    2.67 +  Node *allocNode(Moveable<T> obj) {
    2.68 +    Node *node = (Node *)this->malloc(sizeof(Node));
    2.69 +    if (!node)
    2.70 +      return NULL;
    2.71 +    new (node) Node(obj);
    2.72 +    return node;
    2.73 +  }
    2.74  
    2.75    void freeNode(Node *node) {
    2.76      node->obj.~T();
    2.77 @@ -221,29 +232,9 @@
    2.78      Node *this_;
    2.79    };
    2.80  
    2.81 - public:
    2.82 -  iterator begin() const {
    2.83 -    return iterator(head()->next);
    2.84 -  }
    2.85 -  iterator end() const {
    2.86 -    return iterator(head());
    2.87 -  }
    2.88 -  iterator erase(iterator &where) {
    2.89 -    Node *pNode = where.this_;
    2.90 -    iterator iter(where);
    2.91 -    iter++;
    2.92 -
    2.93 -    pNode->prev->next = pNode->next;
    2.94 -    pNode->next->prev = pNode->prev;
    2.95 -
    2.96 -    freeNode(pNode);
    2.97 -    length_--;
    2.98 -
    2.99 -    return iter;
   2.100 -  }
   2.101 -  iterator insert(iterator where, const T &obj) {
   2.102 -    // Insert obj right before where
   2.103 -    Node *node = allocNode(obj);
   2.104 + private:
   2.105 +  // Insert obj right before where.
   2.106 +  iterator insert(iterator where, Node *node) {
   2.107      if (!node)
   2.108        return where;
   2.109  
   2.110 @@ -259,6 +250,34 @@
   2.111    }
   2.112  
   2.113   public:
   2.114 +  iterator begin() {
   2.115 +    return iterator(head()->next);
   2.116 +  }
   2.117 +  iterator end() {
   2.118 +    return iterator(head());
   2.119 +  }
   2.120 +  iterator erase(iterator where) {
   2.121 +    Node *pNode = where.this_;
   2.122 +    iterator iter(where);
   2.123 +    iter++;
   2.124 +
   2.125 +    pNode->prev->next = pNode->next;
   2.126 +    pNode->next->prev = pNode->prev;
   2.127 +
   2.128 +    freeNode(pNode);
   2.129 +    length_--;
   2.130 +
   2.131 +    return iter;
   2.132 +  }
   2.133 +  iterator insertBefore(iterator where, const T &obj) {
   2.134 +    return insert(where, allocNode(obj));
   2.135 +  }
   2.136 +  iterator insertBefore(iterator where, Moveable<T> obj) {
   2.137 +    return insert(where, allocNode(obj));
   2.138 +  }
   2.139 +
   2.140 + public:
   2.141 +  // Removes one instance of |obj| from the list, if found.
   2.142    void remove(const T &obj) {
   2.143      for (iterator b = begin(); b != end(); b++) {
   2.144        if (*b == obj) {
   2.145 @@ -269,7 +288,7 @@
   2.146    }
   2.147  
   2.148    template <typename U>
   2.149 -  iterator find(const U &equ) const {
   2.150 +  iterator find(const U &equ) {
   2.151      for (iterator iter = begin(); iter != end(); iter++) {
   2.152        if (*iter == equ)
   2.153          return iter;
     3.1 --- a/public/amtl/am-moveable.h	Thu Aug 29 14:16:18 2013 -0400
     3.2 +++ b/public/amtl/am-moveable.h	Thu Aug 29 11:45:28 2013 -0700
     3.3 @@ -61,6 +61,13 @@
     3.4    T &t_;
     3.5  };
     3.6  
     3.7 +template <typename T>
     3.8 +static inline Moveable<T>
     3.9 +Move(T &t)
    3.10 +{
    3.11 +  return Moveable<T>(t);
    3.12 +}
    3.13 +
    3.14  } // namespace ke
    3.15  
    3.16  #endif // _include_amtl_moveable_h_
     4.1 --- a/public/amtl/am-string.h	Thu Aug 29 14:16:18 2013 -0400
     4.2 +++ b/public/amtl/am-string.h	Thu Aug 29 11:45:28 2013 -0700
     4.3 @@ -81,6 +81,9 @@
     4.4      return *this;
     4.5    }
     4.6  
     4.7 +  int compare(const char *str) const {
     4.8 +    return strcmp(chars(), str);
     4.9 +  }
    4.10    int compare(const AString &other) const {
    4.11      return strcmp(chars(), other.chars());
    4.12    }
     5.1 --- a/public/amtl/am-vector.h	Thu Aug 29 14:16:18 2013 -0400
     5.2 +++ b/public/amtl/am-vector.h	Thu Aug 29 11:45:28 2013 -0700
     5.3 @@ -43,25 +43,31 @@
     5.4  {
     5.5   public:
     5.6    Vector(AllocPolicy = AllocPolicy())
     5.7 -  : data_(NULL),
     5.8 -    nitems_(0),
     5.9 -    maxsize_(0)
    5.10 +   : data_(NULL),
    5.11 +     nitems_(0),
    5.12 +     maxsize_(0)
    5.13    {
    5.14    }
    5.15  
    5.16 +  Vector(Moveable<Vector<T, AllocPolicy> > other) {
    5.17 +    data_ = other->data_;
    5.18 +    nitems_ = other->nitems_;
    5.19 +    maxsize_ = other->maxsize_;
    5.20 +    other->reset();
    5.21 +  }
    5.22 +
    5.23    ~Vector() {
    5.24      zap();
    5.25    }
    5.26  
    5.27 -  void steal(Vector &other) {
    5.28 -    zap();
    5.29 -    data_ = other.data_;
    5.30 -    nitems_ = other.nitems_;
    5.31 -    maxsize_ = other.maxsize_;
    5.32 -    other.reset();
    5.33 +  bool append(const T &item) {
    5.34 +    if (!growIfNeeded(1))
    5.35 +      return false;
    5.36 +    new (&data_[nitems_]) T(item);
    5.37 +    nitems_++;
    5.38 +    return true;
    5.39    }
    5.40 -
    5.41 -  bool append(const T &item) {
    5.42 +  bool append(Moveable<T> item) {
    5.43      if (!growIfNeeded(1))
    5.44        return false;
    5.45      new (&data_[nitems_]) T(item);
    5.46 @@ -73,6 +79,12 @@
    5.47      new (&data_[nitems_]) T(item);
    5.48      nitems_++;
    5.49    }
    5.50 +  void infallibleAppend(Moveable<T> item) {
    5.51 +    assert(growIfNeeded(1));
    5.52 +    new (&data_[nitems_]) T(item);
    5.53 +    nitems_++;
    5.54 +  }
    5.55 +
    5.56    T popCopy() {
    5.57      T t = at(length() - 1);
    5.58      pop();