#include // Provides size_t #include // Provides assert template class Bag { public: // MEMBER CONSTANTS enum { DEFAULT_CAPACITY = 30 }; // Or: // static const size_t DEFAULT_CAPACITY = 30; // CONSTRUCTORS and DESTRUCTOR Bag(size_t initial_capacity = DEFAULT_CAPACITY); Bag(const Bag& source); ~Bag( ); // MODIFICATION MEMBER FUNCTIONS void resize(size_t capacity); void insert(const Item& entry); void remove(const Item& target); void operator +=(const Bag& addend); void operator =(const Bag& source); // CONSTANT MEMBER FUNCTIONS size_t size( ) const { return used; } size_t occurrences(const Item& target) const; Item grab( ) const; // FRIEND FUNCTIONS friend Bag operator +(const Bag& b1, const Bag& b2); friend void operator >> (istream& ins, Bag& b); friend void operator << (ostream& outs, Bag& b); private: Item *data; // Pointer to partially filled dynamic array size_t used; // How much of array is being used size_t capacity; // Current capacity of the Bag }; template Bag::Bag(size_t initial_capacity) { data = new Item[initial_capacity]; capacity = initial_capacity; used = 0; } template Bag::Bag(const Bag& source) { size_t i; // An array index data = new Item[source.capacity]; capacity = source.capacity; used = source.used; for (i = 0; i < used; i++) data[i] = source.data[i]; } template Bag::~Bag( ) { delete [ ] data; } template void Bag::resize(size_t new_capacity) { size_t i; Item *larger_array; if (new_capacity == capacity) return; // The allocated memory is already the right size if (new_capacity < used) new_capacity = used; // Can't allocate less than we are using larger_array = new Item[new_capacity]; for (i = 0; i < used; i++) larger_array[i] = data[i]; delete [ ] data; data = larger_array; capacity = new_capacity; } template void Bag::insert(const Item& entry) { if (used == capacity) resize(used+1); data[used] = entry; used++; } template Item Bag::grab( ) const { size_t i; assert(size( ) > 0); i = (rand( ) % size( )); // i is in the range of 0 to size( ) - 1 return data[i]; } template void Bag::remove(const Item& target) { size_t index; // The location of target in the data array for (index = 0; (index < used) && (data[index] != target); index++); if (index == used) return; // target isn't in the Bag, so no work to do used--; data[index] = data[used]; } template void Bag::operator +=(const Bag& addend) { size_t i; // An array index size_t other_bag_size = addend.used; if (used + other_bag_size < capacity) resize(used + other_bag_size); for (i = 0; i < other_bag_size; i++) { data[used] = addend.data[i]; used++; } } template void Bag::operator =(const Bag& source) { size_t i; Item *new_data; if (capacity != source.capacity) { new_data = new Item[source.capacity]; delete [ ]data; data = new_data; capacity = source.capacity; } used = source.used; for (i = 0; i < used; i++) data[i] = source.data[i]; } template size_t Bag::occurrences(const Item& target) const { size_t answer; // Number of times target occurs size_t i; // An array index answer = 0; for (i = 0; i < used; i++) if (target == data[i]) answer++; return answer; } template Bag operator +(const Bag& b1, const Bag& b2) { Bag answer(b1.capacity + b2.capacity); answer += b1; answer += b2; return answer; } template void operator >> (istream& ins, Bag& b) { Item number; cout << "Enter numbers, a negative number when you are done: "; ins >> number; while (number >= 0) { if (b.size( ) < b.capacity) b.insert(number); else cout << "I have run out of room and can't add that number." << endl; cin >> number; } } template void operator << (ostream& outs, Bag& b) { outs << "( "; for(int i = 0; i < b.used; i++) outs << b.data[i] << " "; outs << ")" << endl; }