]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
templatify arrays
authorrobertc <>
Sat, 18 Jan 2003 21:06:32 +0000 (21:06 +0000)
committerrobertc <>
Sat, 18 Jan 2003 21:06:32 +0000 (21:06 +0000)
include/Array.h
lib/Array.cc
lib/Makefile.am

index f7d75ed3ddb392a5d7dca4cfe5f0a9a28cc55835..9129cc9bd0f69620f1508a53965539c8dff69ddc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: Array.h,v 1.8 2002/10/25 03:13:51 robertc Exp $
+ * $Id: Array.h,v 1.9 2003/01/18 14:06:33 robertc Exp $
  *
  * AUTHOR: Alex Rousskov
  *
 #define SQUID_ARRAY_H
 
 /* see Array.c for more documentation */
-
+#ifndef __cplusplus
 typedef struct {
     int capacity;
     int count;
     void **items;
 } Array;
+#endif
+
+#ifdef __cplusplus
+
+/* iterator support */ 
+template <class C> class VectorIteratorBase {
+  public:
+    VectorIteratorBase();
+    VectorIteratorBase(C &);
+    VectorIteratorBase(size_t, C &);
+    VectorIteratorBase & operator =(VectorIteratorBase const &);
+    bool operator != (VectorIteratorBase const &rhs);
+    bool operator == (VectorIteratorBase const &rhs);
+    VectorIteratorBase & operator ++();
+    VectorIteratorBase operator ++(int);
+    typename C::value_type & operator *() const;
+    typename C::value_type * operator -> () const;
+    ssize_t operator - (VectorIteratorBase const &rhs) const;
+    bool incrementable() const;
+  private:
+    size_t pos;
+    C * theVector;
+};
+  
+template<class E>
+class Vector {
+public:
+    typedef E value_type;
+    typedef E* pointer;
+    typedef VectorIteratorBase<Vector<E> > iterator;
+    typedef VectorIteratorBase<Vector<E> const> const_iterator;
+  
+    void *operator new (size_t);
+    void operator delete (void *);
+    
+    Vector();
+    ~Vector();
+    Vector(Vector const &);
+    Vector &operator = (Vector const &);
+    void clean();
+    void reserve (size_t capacity);
+    void push_back (E);
+    E &back();
+    E pop_back();
+    void preAppend(int app_count);
+    bool empty() const;
+    size_t size() const;
+    iterator begin();
+    const_iterator begin () const;
+    iterator end();
+    const_iterator end () const;
+    
+    size_t capacity;
+    size_t count;
+    E *items;
+};
 
+typedef Vector<void *> Array;
+
+#endif
 
 SQUIDCEXTERN Array *arrayCreate(void);
 SQUIDCEXTERN void arrayInit(Array * s);
@@ -50,5 +109,240 @@ SQUIDCEXTERN void arrayDestroy(Array * s);
 SQUIDCEXTERN void arrayAppend(Array * s, void *obj);
 SQUIDCEXTERN void arrayPreAppend(Array * s, int app_count);
 
+#ifdef __cplusplus
+
+template<class E>
+void *
+Vector<E>::operator new(size_t size)
+{
+    return xmalloc (size);
+}
+
+template<class E>
+void
+Vector<E>::operator delete (void *address)
+{
+    xfree (address);
+}
+
+template<class E>
+Vector<E>::Vector() : capacity (0), count(0), items (NULL)
+{
+}
+
+template<class E>
+Vector<E>::~Vector() 
+{
+    clean();
+}
+
+template<class E>
+void
+Vector<E>::clean()
+{
+    /* could also warn if some objects are left */
+    delete[] items;
+    items = NULL;
+    capacity = 0;
+    count = 0;
+}
+
+/* grows internal buffer to satisfy required minimal capacity */
+template<class E>
+void
+Vector<E>::reserve(size_t min_capacity)
+{
+    const int min_delta = 16;
+    int delta;
+    if (capacity >= min_capacity)
+       return;
+    delta = min_capacity;
+    /* make delta a multiple of min_delta */
+    delta += min_delta - 1;
+    delta /= min_delta;
+    delta *= min_delta;
+    /* actual grow */
+    if (delta < 0)
+       delta = min_capacity - capacity;
+    E*newitems = new E[capacity + delta];
+    for (size_t counter = 0; counter < size(); ++counter) {
+       newitems[counter] = items[counter];
+    }
+    capacity += delta;
+    delete[]items;
+    items = newitems;
+}
+
+template<class E>
+void
+Vector<E>::push_back(E obj)
+{
+    if (size() >= capacity)
+       reserve (size() + 1);
+    items[count++] = obj;
+}
+
+template<class E>
+E
+Vector<E>::pop_back()
+{
+    assert (size());
+    value_type result = items[--count];
+    items[count] = value_type();
+    return result;
+}
+
+template<class E>
+E &
+Vector<E>::back()
+{
+    assert (size());
+    return items[size() - 1];
+}
+
+/* if you are going to append a known and large number of items, call this first */
+template<class E>
+void
+Vector<E>::preAppend(int app_count)
+{
+    if (size() + app_count > capacity)
+       reserve(size() + app_count);
+}
+
+template<class E>
+Vector<E> &
+Vector<E>::operator = (Vector const &old)
+{
+    clean();
+    reserve (old.size());
+    for (size_t counter = 0; counter < old.size(); ++counter)
+       push_back (old.items[counter]);
+    return *this;
+}
+
+template<class E>
+bool
+Vector<E>::empty() const
+{
+    return size() == 0;
+}
+
+template<class E>
+size_t
+Vector<E>::size() const
+{
+    return count;
+}
+
+template<class E>
+Vector<E>::iterator
+Vector<E>::begin()
+{
+    return iterator (0, *this);
+}
+
+template<class E>
+Vector<E>::iterator
+Vector<E>::end()
+{
+    return iterator(size(), *this);
+}
+
+template<class E>
+Vector<E>::const_iterator
+Vector<E>::begin() const
+{
+    return const_iterator (0, *this);
+}
+
+template<class E>
+Vector<E>::const_iterator
+Vector<E>::end() const
+{
+    return const_iterator(size(), *this);
+}
+
+
+template<class C>
+VectorIteratorBase<C>::VectorIteratorBase() : pos(0), theVector(NULL)
+{
+}
+
+template<class C>
+VectorIteratorBase<C>::VectorIteratorBase(C &container) : pos(container.begin()), theVector(&container)
+{
+}
+
+template<class C>
+VectorIteratorBase<C>::VectorIteratorBase(size_t aPos, C &container) : pos(aPos), theVector(&container) {}
+
+template<class C>
+bool VectorIteratorBase<C>:: operator != (VectorIteratorBase const &rhs)
+{
+    assert (theVector);
+    return pos != rhs.pos;
+}
+
+template<class C>
+bool VectorIteratorBase<C>:: operator == (VectorIteratorBase const &rhs)
+{
+    assert (theVector);
+    return pos == rhs.pos;
+}
+
+template<class C>
+bool 
+VectorIteratorBase<C>::incrementable() const
+{
+    assert (theVector);
+    return pos != theVector->size();
+}
+
+template<class C>
+VectorIteratorBase<C> & VectorIteratorBase<C>:: operator ++()
+{
+    assert (theVector);
+    if (!incrementable())
+       fatal ("domain error");
+    ++pos;
+    return *this;
+}
+
+template<class C>
+VectorIteratorBase<C> VectorIteratorBase<C>:: operator ++(int)
+{
+    VectorIteratorBase result(*this);
+    ++*this;
+    return result;
+}
+
+template<class C>
+typename C::value_type & VectorIteratorBase<C>::operator *() const
+{
+    return theVector->items[pos];
+}
+
+template<class C>
+typename C::value_type * VectorIteratorBase<C>::operator -> () const
+{
+    return &theVector->items[pos];
+}
+
+template<class C>
+VectorIteratorBase<C>&
+VectorIteratorBase<C>::operator =(VectorIteratorBase const &old) {
+    pos = old.pos;
+    theVector = old.theVector;
+    return *this;
+}
+
+template<class C>
+ssize_t
+VectorIteratorBase<C>::operator - (VectorIteratorBase const &rhs) const
+{
+    assert(theVector == rhs.theVector);
+    return pos - rhs.pos;
+}
+#endif
 
 #endif /* SQUID_ARRAY_H */
index 463e8ee984bb95ba881aebbb2df875a9c14db8ec..65b478af00e26da8b743dcb411d09e1d295a0224 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: Array.cc,v 1.8 2003/01/18 04:50:39 robertc Exp $
+ * $Id: Array.cc,v 1.9 2003/01/18 14:06:32 robertc Exp $
  *
  * AUTHOR: Alex Rousskov
  *
 #include "util.h"
 #include "Array.h"
 
-static void arrayGrow(Array * a, int min_capacity);
-
-Array *
-arrayCreate(void)
-{
-    Array *a = new Array;
-    arrayInit(a);
-    return a;
-}
+Array *arrayCreate(void) {return new Array;}
+void arrayClean(Array * s) {s->clean();}
+void arrayDestroy(Array * s) { delete s;}
+void arrayAppend(Array * s, void *obj) {s->push_back(obj);}
+void arrayPreAppend(Array * s, int app_count) {s->preAppend(app_count);}
 
 void
 arrayInit(Array * a)
@@ -68,60 +64,3 @@ arrayInit(Array * a)
     assert(a);
     memset(a, 0, sizeof(Array));
 }
-
-void
-arrayClean(Array * a)
-{
-    assert(a);
-    /* could also warn if some objects are left */
-    xfree(a->items);
-    a->items = NULL;
-}
-
-void
-arrayDestroy(Array * a)
-{
-    assert(a);
-    arrayClean(a);
-    delete a;
-}
-
-void
-arrayAppend(Array * a, void *obj)
-{
-    assert(a);
-    if (a->count >= a->capacity)
-       arrayGrow(a, a->count + 1);
-    a->items[a->count++] = obj;
-}
-
-/* if you are going to append a known and large number of items, call this first */
-void
-arrayPreAppend(Array * a, int app_count)
-{
-    assert(a);
-    if (a->count + app_count > a->capacity)
-       arrayGrow(a, a->count + app_count);
-}
-
-/* grows internal buffer to satisfy required minimal capacity */
-static void
-arrayGrow(Array * a, int min_capacity)
-{
-    const int min_delta = 16;
-    int delta;
-    assert(a->capacity < min_capacity);
-    delta = min_capacity;
-    /* make delta a multiple of min_delta */
-    delta += min_delta - 1;
-    delta /= min_delta;
-    delta *= min_delta;
-    /* actual grow */
-    assert(delta > 0);
-    a->capacity += delta;
-    a->items = (void **) (a->items ?
-       xrealloc(a->items, a->capacity * sizeof(void *)) :
-         xmalloc(a->capacity * sizeof(void *)));
-    /* reset, just in case */
-    memset(a->items + a->count, 0, (a->capacity - a->count) * sizeof(void *));
-}
index f8079a6eb121f536af3cfd3ac4e1776cf00af41d..418e85dc7882e979579129605ef0fa1cce377f22 100644 (file)
@@ -1,6 +1,6 @@
 ## Process this file with automake to produce Makefile.in
 #
-#  $Id: Makefile.am,v 1.5 2002/10/02 11:06:30 robertc Exp $
+#  $Id: Makefile.am,v 1.6 2003/01/18 14:06:32 robertc Exp $
 #
 
 if ENABLE_XPROF_STATS
@@ -34,7 +34,7 @@ EXTRA_libmiscutil_a_SOURCES = \
        snprintf.c
 libmiscutil_a_SOURCES = \
        MemPool.c \
-       Array.c \
+       Array.cc \
        base64.c \
        getfullhostname.c \
        hash.c \