to avoid stability issues related to std::vector migration.
#include "MemPool.h"
-#include <stack>
-
/// \ingroup MemPoolsAPI
class MemPoolMalloc : public MemImplementingAllocator
{
virtual void *allocate();
virtual void deallocate(void *, bool aggressive);
private:
- std::stack<void *> freelist;
+ Stack<void *> freelist;
};
#endif /* _MEM_POOL_MALLOC_H_ */
--- /dev/null
+/*
+ * AUTHOR: Alex Rousskov
+ *
+ * SQUID Web Proxy Cache http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ * Squid is the result of efforts by numerous individuals from
+ * the Internet community; see the CONTRIBUTORS file for full
+ * details. Many organizations have provided support for Squid's
+ * development; see the SPONSORS file for full details. Squid is
+ * Copyrighted (C) 2001 by the Regents of the University of
+ * California; see the COPYRIGHT file for full details. Squid
+ * incorporates software developed and/or copyrighted by other
+ * sources; see the CREDITS file for full details.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+
+#ifndef SQUID_STACK_H
+#define SQUID_STACK_H
+
+#include "base/Vector.h"
+
+/* RBC: 20030714 Composition might be better long-term, but for now,
+ * there's no reason to do so.
+ */
+
+template <class S = void *>
+
+class Stack : public Vector<S>
+{
+public:
+ using Vector<S>::count;
+ using Vector<S>::items;
+ typedef typename Vector<S>::value_type value_type;
+ typedef typename Vector<S>::pointer pointer;
+ value_type pop() {
+ if (!count)
+ return value_type();
+
+ value_type result = items[--count];
+
+ this->items[count] = value_type();
+
+ return result;
+ }
+
+ /* todo, fatal on empty Top call */
+ value_type top() const {
+ return count ? items[count - 1] : value_type();
+ }
+};
+
+#endif /* SQUID_STACK_H */
#if defined(__cplusplus)
-#include "fatal.h"
-
-#include <stack>
+#include "Stack.h"
template <class V>
class SplayNode
void advance();
void addLeftPath(SplayNode<V> *aNode);
void init(SplayNode<V> *);
- std::stack<SplayNode<V> *> toVisit;
+ Stack<SplayNode<V> *> toVisit;
};
template <class V>
bool
SplayConstIterator<V>::operator == (SplayConstIterator const &right) const
{
- if (toVisit.empty() && right.toVisit.empty())
- return true;
- if (!toVisit.empty() && !right.toVisit.empty())
- return toVisit.top() == right.toVisit.top();
- // only one of the two is empty
- return false;
+ return toVisit.top() == right.toVisit.top();
}
template <class V>
void
SplayConstIterator<V>::advance()
{
- if (toVisit.empty())
+ if (toVisit.size() == 0)
return;
toVisit.pop();
- if (toVisit.empty())
+ if (toVisit.size() == 0)
return;
- // not empty
- SplayNode<V> *currentNode = toVisit.top();
- toVisit.pop();
+ SplayNode<V> *currentNode = toVisit.pop();
addLeftPath(currentNode->right);
- toVisit.push(currentNode);
+ toVisit.push_back(currentNode);
}
template <class V>
return;
do {
- toVisit.push(aNode);
+ toVisit.push_back(aNode);
aNode = aNode->left;
} while (aNode != NULL);
}
void *
MemPoolMalloc::allocate()
{
- void *obj = NULL;
- if (!freelist.empty()) {
- obj = freelist.top();
- freelist.pop();
- }
+ void *obj = freelist.pop();
if (obj) {
memMeterDec(meter.idle);
++saved_calls;
if (doZero)
memset(obj, 0, obj_size);
memMeterInc(meter.idle);
- freelist.push(obj);
+ freelist.push_back(obj);
}
}
void
MemPoolMalloc::clean(time_t maxage)
{
- while (!freelist.empty()) {
- void *obj = freelist.top();
- freelist.pop();
+ while (void *obj = freelist.pop()) {
memMeterDec(meter.idle);
memMeterDec(meter.alloc);
xfree(obj);
#include "auth/Gadgets.h"
#include "auth/User.h"
+#include "base/Vector.h"
#include "CompositePoolNode.h"
#include "DelayBucket.h"
#include "DelayIdComposite.h"
return visitor;
}
+template <class S>
+class Stack;
+
+template <class E, class T>
+T& for_each(Stack<E> const &collection, T& visitor)
+{
+ for (size_t index = 0; index < collection.count; ++index)
+ visitor(*(typename T::argument_type const *)collection.items[index]);
+
+ return visitor;
+};
+
/* RBC 20030718 - use this to provide instance expecting classes a pointer to a
* singleton
*/
#include <algorithm>
-/* XXX: the whole set of API managing the entries vector should be rethought
- * after the parse4r-ng effort is complete.
- */
-
/*
* On naming conventions:
*
void
HttpHeader::clean()
{
+ HttpHeaderPos pos = HttpHeaderInitPos;
+ HttpHeaderEntry *e;
assert(owner > hoNone && owner < hoEnd);
debugs(55, 7, "cleaning hdr: " << this << " owner: " << owner);
HttpHeaderStats[owner].busyDestroyedCount += entries.size() > 0;
} // if (owner <= hoReply)
- for (std::vector<HttpHeaderEntry *>::iterator i = entries.begin(); i != entries.end(); ++i) {
- HttpHeaderEntry *e = *i;
- if (e == NULL)
- continue;
+ while ((e = getEntry(&pos))) {
+ /* tmp hack to try to avoid coredumps */
+
if (e->id < 0 || e->id >= HDR_ENUM_END) {
- debugs(55, DBG_CRITICAL, "BUG: invalid entry (" << e->id << "). Ignored.");
+ debugs(55, DBG_CRITICAL, "HttpHeader::clean BUG: entry[" << pos << "] is invalid (" << e->id << "). Ignored.");
} else {
if (owner <= hoReply)
HttpHeaderStats[owner].fieldTypeDistr.count(e->id);
+ /* yes, this deletion leaves us in an inconsistent state */
delete e;
}
}
-
entries.clear();
httpHeaderMaskInit(&mask, 0);
len = 0;
tests/testSBuf \
tests/testSBufList \
tests/testConfigParser \
- tests/testStatHist
+ tests/testStatHist \
+ tests/testVector
if HAVE_FS_ROCK
check_PROGRAMS += tests/testRock
$(COMPAT_LIB)
tests_testStatHist_DEPENDENCIES = $(SQUID_CPPUNIT_LA)
+tests_testVector_SOURCES = \
+ tests/testVector.cc \
+ tests/testMain.cc \
+ tests/testVector.h
+nodist_tests_testVector_SOURCES = \
+ $(TESTSOURCES)
+tests_testVector_LDADD= \
+ $(SQUID_CPPUNIT_LIBS) \
+ $(COMPAT_LIB) \
+ $(XTRA_LIBS)
+tests_testVector_LDFLAGS = $(LIBADD_DL)
+tests_testVector_DEPENDENCIES = \
+ $(SQUID_CPPUNIT_LA)
+
+
TESTS += testHeaders
## Special Universal .h dependency test script
RunnersRegistry.h \
Subscription.h \
TextException.cc \
- TextException.h
+ TextException.h \
+ Vector.cc \
+ Vector.h
EXTRA_PROGRAMS = \
testCharacterSet
--- /dev/null
+/*
+ * AUTHOR: Alex Rousskov
+ *
+ * SQUID Web Proxy Cache http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ * Squid is the result of efforts by numerous individuals from
+ * the Internet community; see the CONTRIBUTORS file for full
+ * details. Many organizations have provided support for Squid's
+ * development; see the SPONSORS file for full details. Squid is
+ * Copyrighted (C) 2001 by the Regents of the University of
+ * California; see the COPYRIGHT file for full details. Squid
+ * incorporates software developed and/or copyrighted by other
+ * sources; see the CREDITS file for full details.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+
+/*
+ * Array is an array of (void*) items with unlimited capacity
+ *
+ * Array grows when arrayAppend() is called and no space is left
+ * Currently, array does not have an interface for deleting an item because
+ * we do not need such an interface yet.
+ */
+
+#include "squid.h"
+#include "base/Vector.h"
+
+#if HAVE_ASSERT_H
+#include <assert.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#endif
--- /dev/null
+/*
+ * AUTHOR: Alex Rousskov
+ *
+ * SQUID Web Proxy Cache http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ * Squid is the result of efforts by numerous individuals from
+ * the Internet community; see the CONTRIBUTORS file for full
+ * details. Many organizations have provided support for Squid's
+ * development; see the SPONSORS file for full details. Squid is
+ * Copyrighted (C) 2001 by the Regents of the University of
+ * California; see the COPYRIGHT file for full details. Squid
+ * incorporates software developed and/or copyrighted by other
+ * sources; see the CREDITS file for full details.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+#ifndef SQUID_ARRAY_H
+#define SQUID_ARRAY_H
+
+/**
+ \todo remove this after replacing with STL
+ */
+
+#include "fatal.h"
+#include "util.h"
+
+/* users of this template also need assert() */
+#include "compat/assert.h"
+
+/* iterator support */
+#include <iterator>
+
+template <class C>
+class VectorIteratorBase
+{
+public:
+ typedef typename C::value_type value_type;
+ typedef std::forward_iterator_tag iterator_category;
+ typedef typename C::pointer pointer;
+ typedef typename C::reference reference;
+ typedef typename C::difference_type difference_type;
+
+ VectorIteratorBase();
+ VectorIteratorBase(C &);
+ VectorIteratorBase(size_t, C &);
+ VectorIteratorBase & operator =(VectorIteratorBase const &);
+ bool operator != (VectorIteratorBase const &rhs) const;
+ bool operator == (VectorIteratorBase const &rhs) const;
+ VectorIteratorBase & operator ++();
+ VectorIteratorBase operator ++(int);
+ typename C::value_type & operator *() const {
+ return theVector->items[pos];
+ }
+
+ typename C::value_type * operator -> () const {
+ return &theVector->items[pos];
+ }
+
+ 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 E& reference;
+ typedef VectorIteratorBase<Vector<E> > iterator;
+ typedef VectorIteratorBase<Vector<E> const> const_iterator;
+ typedef ptrdiff_t difference_type;
+ friend class VectorIteratorBase<Vector<E> >;
+ friend class VectorIteratorBase<Vector<E> const>;
+ void *operator new (size_t);
+ void operator delete (void *);
+
+ Vector();
+ ~Vector();
+ Vector(Vector const &);
+ Vector &operator = (Vector const &);
+ void clear();
+ void reserve (size_t capacity);
+ void push_back (E);
+
+ void insert (E);
+ const E &front() const;
+ E &front();
+ E &back();
+ void pop_back();
+ E shift(); // aka pop_front
+ void prune(E);
+ void preAppend(int app_count);
+ inline bool empty() const;
+ inline size_t size() const;
+ iterator begin();
+ const_iterator begin () const;
+ iterator end();
+ const_iterator end () const;
+ E& at(unsigned i);
+ const E& at(unsigned i) const;
+ inline E& operator [] (unsigned i);
+ inline const E& operator [] (unsigned i) const;
+ E* data() const { return items; }
+
+protected:
+ size_t capacity;
+ size_t count;
+ E *items;
+};
+
+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()
+{
+ clear();
+}
+
+template<class E>
+void
+Vector<E>::clear()
+{
+ /* 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>
+void
+Vector<E>::insert(E obj)
+{
+ if (size() >= capacity)
+ reserve (size() + 1);
+
+ int i;
+
+ for (i = count; i > 0; i--)
+ items[i] = items[i - 1];
+
+ items[i] = obj;
+
+ count += 1;
+}
+
+template<class E>
+E
+Vector<E>::shift()
+{
+ assert (size());
+ value_type result = items[0];
+
+ for (unsigned int i = 1; i < count; i++)
+ items[i-1] = items[i];
+
+ count--;
+
+ /*reset the last (unused) element...*/
+ items[count] = value_type();
+
+ return result;
+}
+
+template<class E>
+void
+Vector<E>::pop_back()
+{
+ assert (size());
+ --count;
+ items[count] = value_type();
+}
+
+template<class E>
+E &
+Vector<E>::back()
+{
+ assert (size());
+ return items[size() - 1];
+}
+
+template<class E>
+const E &
+Vector<E>::front() const
+{
+ assert (size());
+ return items[0];
+}
+
+template<class E>
+E &
+Vector<E>::front()
+{
+ assert (size());
+ return items[0];
+}
+
+template<class E>
+void
+Vector<E>::prune(E item)
+{
+ unsigned int n = 0;
+ for (unsigned int i = 0; i < count; i++) {
+ if (items[i] != item) {
+ if (i != n)
+ items[n] = items[i];
+ n++;
+ }
+ }
+
+ count = n;
+}
+
+/* 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 (Vector<E> const &rhs)
+{
+ items = NULL;
+ capacity = 0;
+ count = 0;
+ reserve (rhs.size());
+
+ for (size_t counter = 0; counter < rhs.size(); ++counter)
+ push_back (rhs.items[counter]);
+}
+
+template<class E>
+Vector<E> &
+Vector<E>::operator = (Vector<E> const &old)
+{
+ clear();
+ 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>
+typename Vector<E>::iterator
+Vector<E>::begin()
+{
+ return iterator (0, *this);
+}
+
+template<class E>
+typename Vector<E>::iterator
+Vector<E>::end()
+{
+ return iterator(size(), *this);
+}
+
+template<class E>
+typename Vector<E>::const_iterator
+Vector<E>::begin() const
+{
+ return const_iterator (0, *this);
+}
+
+template<class E>
+typename Vector<E>::const_iterator
+Vector<E>::end() const
+{
+ return const_iterator(size(), *this);
+}
+
+template<class E>
+E &
+Vector<E>::at(unsigned i)
+{
+ assert (size() > i);
+ return operator[](i);
+}
+
+template<class E>
+const E &
+Vector<E>::at(unsigned i) const
+{
+ assert (size() > i);
+ return operator[](i);
+}
+
+template<class E>
+E &
+Vector<E>::operator [] (unsigned i)
+{
+ return items[i];
+}
+
+template<class E>
+const E &
+Vector<E>::operator [] (unsigned i) const
+{
+ return items[i];
+}
+
+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<C> const &rhs) const
+{
+ assert (theVector);
+ return pos != rhs.pos;
+}
+
+template<class C>
+bool VectorIteratorBase<C>:: operator == (VectorIteratorBase<C> const &rhs) const
+{
+ 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>
+VectorIteratorBase<C>&
+VectorIteratorBase<C>::operator =(VectorIteratorBase<C> const &old)
+{
+ pos = old.pos;
+ theVector = old.theVector;
+ return *this;
+}
+
+template<class C>
+ssize_t
+VectorIteratorBase<C>::operator - (VectorIteratorBase<C> const &rhs) const
+{
+ assert(theVector == rhs.theVector);
+ return pos - rhs.pos;
+}
+
+#endif /* SQUID_ARRAY_H */
#include "cbdata.h"
#include "mgr/Registration.h"
#include "Store.h"
+#if USE_CBDATA_DEBUG
+#include "Stack.h"
+#endif
#include "Generic.h"
#include <climits>
-#if USE_CBDATA_DEBUG
-#include <algorithm>
-#include <vector>
-#endif
#if WITH_VALGRIND
#define HASHED_CBDATA 1
dlink_node link;
const char *file;
int line;
- std::vector<CBDataCall*> calls; // used as a stack with random access operator
+ Stack<CBDataCall*> calls;
#endif
/* cookie used while debugging */
cbdata::~cbdata()
{
#if USE_CBDATA_DEBUG
+ CBDataCall *aCall;
- while (!calls.empty()) {
- delete calls.back();
- calls.pop_back();
- }
+ while ((aCall = calls.pop()))
+ delete aCall;
#endif
c->file = file;
c->line = line;
- c->calls = std::vector<CBDataCall *> ();
+ c->calls = Stack<CBDataCall *> ();
c->addHistory("Alloc", file, line);
dlinkAdd(c, &c->link, &cbdataEntries);
debugs(45, 3, "cbdataAlloc: " << p << " " << file << ":" << line);
struct CBDataCallDumper : public unary_function<CBDataCall, void> {
CBDataCallDumper (StoreEntry *anEntry):where(anEntry) {}
- void operator()(CBDataCall * const &x) {
- storeAppendPrintf(where, "%s\t%s\t%d\n", x->label, x->file, x->line);
+ void operator()(CBDataCall const &x) {
+ storeAppendPrintf(where, "%s\t%s\t%d\n", x.label, x.file, x.line);
}
StoreEntry *where;
CBDataDumper::operator()(x);
storeAppendPrintf(where, "\n");
storeAppendPrintf(where, "Action\tFile\tLine\n");
- std::for_each (x.calls.begin(), x.calls.end(), callDumper);
+ for_each (x.calls,callDumper);
storeAppendPrintf(where, "\n");
}
#include "RequestFlags.h"
#include "SquidConfig.h"
#include "SquidTime.h"
+#include "Stack.h"
#include "StatCounters.h"
#include "stmem.h"
#include "Store.h"
#endif
#include <climits>
-#include <stack>
#define REBUILD_TIMESTAMP_DELTA_MAX 2
/*
* local variables
*/
-static std::stack<StoreEntry*> LateReleaseStack;
+static Stack<StoreEntry*> LateReleaseStack;
MemAllocator *StoreEntry::pool = NULL;
StorePointer Store::CurrentRoot = NULL;
// lock the entry until rebuilding is done
lock("storeLateRelease");
setReleaseFlag();
- LateReleaseStack.push(this);
+ LateReleaseStack.push_back(this);
} else {
destroyStoreEntry(static_cast<hash_link *>(this));
// "this" is no longer valid
storeLateRelease(void *unused)
{
StoreEntry *e;
+ int i;
static int n = 0;
if (StoreController::store_dirs_rebuilding) {
return;
}
- // TODO: this works but looks unelegant.
- for (int i = 0; i < 10; ++i) {
- if (LateReleaseStack.empty()) {
+ for (i = 0; i < 10; ++i) {
+ e = LateReleaseStack.empty() ? NULL : LateReleaseStack.pop();
+
+ if (e == NULL) {
+ /* done! */
debugs(20, DBG_IMPORTANT, "storeLateRelease: released " << n << " objects");
return;
- } else {
- e = LateReleaseStack.top();
- LateReleaseStack.pop();
}
e->unlock("storeLateRelease");
--- /dev/null
+#define SQUID_UNIT_TEST 1
+#include "squid.h"
+#include "base/Vector.h"
+#include "tests/testVector.h"
+
+#include <cppunit/TestAssert.h>
+
+CPPUNIT_TEST_SUITE_REGISTRATION( testVector );
+
+void testVector::all()
+{
+ CPPUNIT_ASSERT_EQUAL(1 , 1);
+ Vector<int> aArray;
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), aArray.size());
+ aArray.push_back(2);
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aArray.size());
+ CPPUNIT_ASSERT_EQUAL(2, aArray.back());
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aArray.size());
+}
--- /dev/null
+#ifndef SQUID_SRC_TESTS_TESTVECTOR_H
+#define SQUID_SRC_TESTS_TESTVECTOR_H
+
+#include <cppunit/extensions/HelperMacros.h>
+
+/*
+ * A test case that is designed to produce
+ * example errors and failures
+ *
+ */
+
+class testVector : public CPPUNIT_NS::TestFixture
+{
+ CPPUNIT_TEST_SUITE( testVector );
+ CPPUNIT_TEST( all );
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+
+protected:
+ void all();
+};
+
+#endif
TESTS += debug \
syntheticoperators \
VirtualDeleteOperator \
+ StackTest \
splay\
MemPoolTest\
mem_node_test\
mem_node_test\
mem_hdr_test \
splay \
+ StackTest \
syntheticoperators \
VirtualDeleteOperator
splay_SOURCES = splay.cc
+StackTest_SOURCES = StackTest.cc $(DEBUG_SOURCE)
+
syntheticoperators_SOURCES = syntheticoperators.cc $(DEBUG_SOURCE)
VirtualDeleteOperator_SOURCES = VirtualDeleteOperator.cc $(DEBUG_SOURCE)
--- /dev/null
+
+/*
+ * DEBUG: section 19 Store Memory Primitives
+ * AUTHOR: Robert Collins
+ *
+ * SQUID Web Proxy Cache http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ * Squid is the result of efforts by numerous individuals from
+ * the Internet community; see the CONTRIBUTORS file for full
+ * details. Many organizations have provided support for Squid's
+ * development; see the SPONSORS file for full details. Squid is
+ * Copyrighted (C) 2001 by the Regents of the University of
+ * California; see the COPYRIGHT file for full details. Squid
+ * incorporates software developed and/or copyrighted by other
+ * sources; see the CREDITS file for full details.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ * Copyright (c) 2003 Robert Collins <robertc@squid-cache.org>
+ */
+
+#include "squid.h"
+#include "Stack.h"
+
+int
+main(int argc, char **argv)
+{
+ Stack<int> aStack;
+ assert (aStack.size() == 0);
+ aStack.push_back(2);
+ assert (aStack.size() == 1);
+ assert (aStack.top() == 2);
+ assert (aStack.pop() == 2);
+ assert (aStack.size() == 0);
+ Stack<> oldStack;
+ assert (oldStack.size() == 0);
+ oldStack.push_back(&aStack);
+ assert (oldStack.size() == 1);
+ assert (oldStack.top() == &aStack);
+ assert (oldStack.pop() == &aStack);
+ assert (oldStack.size() == 0);
+ return 0;
+}