/* * CS70, Spring 2001 * * Implementation of a simple container class. The class allows the * user to put stuff in and get it back out, not necessarily in the * same order. An iterator is also provided, so that the container * contents can be examined nondestructively. */ #include "dumbcontainer.hh" #include /* * Table of contents: the following routines are defined in this file. * * DumbContainer::DumbContainer(unsigned int maxSize_); * DumbContainer::~DumbContainer(); * bool DumbContainer::add(const string& info); * // Add a string to the container * // ..returns false if add failed * string DumbContainer::remove(); * // Remove and return a string * bool DumbContainer::isEmpty() const; * // Test whether container has stuff * * DumbContainerIterator::DumbContainerIterator( * const DumbContainer& target_); * DumbContainerIterator::DumbContainerIterator( * const DumbContainerIterator& source); * DumbContainerIterator::~DumbContainerIterator(); * DumbContainerIterator& * DumbContainerIterator::operator=( * const DumbContainerIterator& source); * DumbContainerIterator::operator bool() const; * // Return true if more data left * DumbContainerIterator& * DumbContainerIterator::operator++(); * // Preincrement the iterator * DumbContainerIterator * DumbContainerIterator::operator++(int); * // Postincrement the iterator * string& DumbContainerIterator::operator*() const; * // Return current string * string* DumbContainerIterator::operator->() const; * // Return current string */ /* * Construct a dumb container with a specified maximum size. */ DumbContainer::DumbContainer( unsigned int maxSize_) // Maximum no. of strings we can hold : maxSize(maxSize), currentSize(0), strings(new string[maxSize_]) { } /* * Destructor for dumb containers. */ DumbContainer::~DumbContainer() { delete[] strings; } /* * Add a string to a dumb container. Returns true if add succeeded, * false if there was no room. */ bool DumbContainer::add( const string& info) // String to add { if (currentSize >= maxSize) return false; // Sorry, no room strings[currentSize] = info; /* * Just to be perverse (and to illustrate the fact that containers * don't have to keep things in any particular order), randomize * things a bit. */ if (currentSize & 1) { string temp(strings[currentSize]); strings[currentSize] = strings[0]; strings[0] = temp; } currentSize++; return true; // Add was successful } /* * Remove a string from a dumb container and return it. By design, * the order of removal is undefined. All the user can be assured of * is that all strings inserted can eventually be removed. */ string DumbContainer::remove() { if (currentSize == 0) return string(""); // If empty, give a null string return strings[--currentSize]; } /* * Test whether a dumb container is empty. */ bool DumbContainer::isEmpty() const { return currentSize == 0; } /* * Create an iterator pointing at a specified dumb container. */ DumbContainerIterator::DumbContainerIterator( const DumbContainer& target_) // Container we'll iterate over : target(&target_), position(0) { } /* * Copy constructor for the dumb-container iterator. */ DumbContainerIterator::DumbContainerIterator( const DumbContainerIterator& source) // Iterator to copy : target(source.target), position(source.position) { } DumbContainerIterator::~DumbContainerIterator() { } /* * Assignment for dumb-container iterators. */ DumbContainerIterator& DumbContainerIterator::operator=( const DumbContainerIterator& source) { if (this == &source) return *this; target = source.target; position = source.position; return *this; } /* * Test whether a dumb-container iterator will be able to return more * data. */ DumbContainerIterator::operator bool() const { return position < target->currentSize; } /* * Preincrement a dumb-container iterator. */ DumbContainerIterator& DumbContainerIterator::operator++() { if (*this) position++; return *this; } /* * Postincrement a dumb-container iterator. */ DumbContainerIterator DumbContainerIterator::operator++( int ) // Dummy argument required by C++ { DumbContainerIterator previous(*this); ++(*this); return previous; } /* * Return the string currently pointed to by a dumb-container * iterator. If called on an expired iterator, returns a random * string from the container; if called on an expired iterator for an * empty container, returns an empty string. */ string& DumbContainerIterator::operator*() const { if (*this) return target->strings[position]; else return target->strings[0]; } /* * Return the string currently pointed to by a dumb-container * iterator. If called on an expired iterator, returns a NULL pointer * (which will probably segfault the caller; life is tough). */ string* DumbContainerIterator::operator->() const { if (*this) return &target->strings[position]; else return NULL; }