From: robertc <> Date: Sat, 18 Jan 2003 21:06:32 +0000 (+0000) Subject: templatify arrays X-Git-Tag: SQUID_3_0_PRE1~446 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ec2436ff0a68ced694ec8e68f04f9cbfce2e7596;p=thirdparty%2Fsquid.git templatify arrays --- diff --git a/include/Array.h b/include/Array.h index f7d75ed3dd..9129cc9bd0 100644 --- a/include/Array.h +++ b/include/Array.h @@ -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 * @@ -35,13 +35,72 @@ #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 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 Vector { +public: + typedef E value_type; + typedef E* pointer; + typedef VectorIteratorBase > iterator; + typedef VectorIteratorBase 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 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 +void * +Vector::operator new(size_t size) +{ + return xmalloc (size); +} + +template +void +Vector::operator delete (void *address) +{ + xfree (address); +} + +template +Vector::Vector() : capacity (0), count(0), items (NULL) +{ +} + +template +Vector::~Vector() +{ + clean(); +} + +template +void +Vector::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 +void +Vector::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 +void +Vector::push_back(E obj) +{ + if (size() >= capacity) + reserve (size() + 1); + items[count++] = obj; +} + +template +E +Vector::pop_back() +{ + assert (size()); + value_type result = items[--count]; + items[count] = value_type(); + return result; +} + +template +E & +Vector::back() +{ + assert (size()); + return items[size() - 1]; +} + +/* if you are going to append a known and large number of items, call this first */ +template +void +Vector::preAppend(int app_count) +{ + if (size() + app_count > capacity) + reserve(size() + app_count); +} + +template +Vector & +Vector::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 +bool +Vector::empty() const +{ + return size() == 0; +} + +template +size_t +Vector::size() const +{ + return count; +} + +template +Vector::iterator +Vector::begin() +{ + return iterator (0, *this); +} + +template +Vector::iterator +Vector::end() +{ + return iterator(size(), *this); +} + +template +Vector::const_iterator +Vector::begin() const +{ + return const_iterator (0, *this); +} + +template +Vector::const_iterator +Vector::end() const +{ + return const_iterator(size(), *this); +} + + +template +VectorIteratorBase::VectorIteratorBase() : pos(0), theVector(NULL) +{ +} + +template +VectorIteratorBase::VectorIteratorBase(C &container) : pos(container.begin()), theVector(&container) +{ +} + +template +VectorIteratorBase::VectorIteratorBase(size_t aPos, C &container) : pos(aPos), theVector(&container) {} + +template +bool VectorIteratorBase:: operator != (VectorIteratorBase const &rhs) +{ + assert (theVector); + return pos != rhs.pos; +} + +template +bool VectorIteratorBase:: operator == (VectorIteratorBase const &rhs) +{ + assert (theVector); + return pos == rhs.pos; +} + +template +bool +VectorIteratorBase::incrementable() const +{ + assert (theVector); + return pos != theVector->size(); +} + +template +VectorIteratorBase & VectorIteratorBase:: operator ++() +{ + assert (theVector); + if (!incrementable()) + fatal ("domain error"); + ++pos; + return *this; +} + +template +VectorIteratorBase VectorIteratorBase:: operator ++(int) +{ + VectorIteratorBase result(*this); + ++*this; + return result; +} + +template +typename C::value_type & VectorIteratorBase::operator *() const +{ + return theVector->items[pos]; +} + +template +typename C::value_type * VectorIteratorBase::operator -> () const +{ + return &theVector->items[pos]; +} + +template +VectorIteratorBase& +VectorIteratorBase::operator =(VectorIteratorBase const &old) { + pos = old.pos; + theVector = old.theVector; + return *this; +} + +template +ssize_t +VectorIteratorBase::operator - (VectorIteratorBase const &rhs) const +{ + assert(theVector == rhs.theVector); + return pos - rhs.pos; +} +#endif #endif /* SQUID_ARRAY_H */ diff --git a/lib/Array.cc b/lib/Array.cc index 463e8ee984..65b478af00 100644 --- a/lib/Array.cc +++ b/lib/Array.cc @@ -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 * @@ -52,15 +52,11 @@ #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 *)); -} diff --git a/lib/Makefile.am b/lib/Makefile.am index f8079a6eb1..418e85dc78 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -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 \