#include "BagOp.h" #include #include using std::ostream; using std::istream; using std::ios; using std::setw; using std::setfill; using std::cerr; using std::endl; int Bag::CAPLIMIT = 100; Bag::Bag():sz(0), capacity(CAPLIMIT) { intbag = new int[capacity]; } Bag::Bag(int cap):sz(0), capacity(cap) { if (capacity > CAPLIMIT) { capacity = CAPLIMIT; cerr << "changing capacity to limit: " << CAPLIMIT << endl; } intbag = new int[capacity]; } // copy constructor - DEEP copy Bag::Bag(const Bag & frombag) { sz = frombag.sz; capacity = frombag.capacity; intbag = new int[capacity]; for (int i = 0; i < sz; i++) // makes it deep copy intbag[i] = frombag.intbag[i]; } // destructor Bag::~Bag() { delete[]intbag; // release memory!! } // modifiers bool Bag::add(int n) { if (sz == capacity) // bag is full return false; intbag[sz++] = n; return true; } int Bag::where(int n) const { for (int i = 0; i < sz; i++) if (intbag[i] == n) return i; return -1; } bool Bag::find(int n) const { return where(n) != -1; } bool Bag::remove(int n) { int w = where(n); if (w == -1) return false; intbag[w] = intbag[--sz]; return true; } ostream & Bag::write(ostream & os) const { char oldfill = os.fill('*'); os << '{'; os.setf(ios::fixed); os.setf(ios::showpoint); for (int i = 0; i < sz - 1; i++) os << setw(5) << intbag[i] << ", "; os << setfill('0') << setw(5) << intbag[sz - 1] << '}'; os.fill(oldfill); // need to reset to default os.unsetf(ios::fixed); os.unsetf(ios::showpoint); return os; } istream & Bag::read(istream & is) { int value; while (is >> value && !isFull()) { add(value); } return is; } int Bag::CapLimit(int limit) { int temp = CAPLIMIT; CAPLIMIT = limit; return temp; } const Bag & Bag::operator=(const Bag & frombag) { if (this != &frombag) // check for identity, to prevent problems with self assignment { delete[]intbag; // delete old bag sz = frombag.sz; capacity = frombag.capacity; intbag = new int[capacity]; for (int i = 0; i < sz; i++) // makes it deep copy intbag[i] = frombag.intbag[i]; } return *this; } const Bag & Bag::operator+=(const Bag & other) { int newsize = capacity + other.capacity; if (newsize > CAPLIMIT) { newsize = sz + other.sz; if (newsize > CAPLIMIT) { cerr << "can't add them together" << endl; return *this; } } int *tempbag = new int[newsize]; int i; for (i = 0; i < sz; i++) tempbag[i] = intbag[i]; for (int j = 0; j < other.sz; i++, j++) tempbag[i] = other.intbag[j]; sz += other.sz; capacity = newsize; delete[]intbag; // delete old bag intbag = tempbag; return *this; } const int Bag::operator[] (int i) const { if (i >= 0 && i < sz) { return intbag[i]; } cerr << "index out of range" << endl; return 0; } int &Bag::operator[] (int i) // returned value becomes an lvalue { if (i >= 0 && i < sz) { return intbag[i]; } cerr << "index out of range" << endl; return intbag[0]; // must return memory space that exists after function exits } // this assumes elements in same order - should do unordered check // would need to sort intbags for unordered comparison bool Bag::operator==(const Bag & other) const { if (sz == other.sz && capacity == other.capacity) { for (int i = 0; i < sz; i++) if (intbag[i] != other.intbag[i]) return false; return true; } else return false; } bool Bag::operator!=(const Bag & other) const { return !(*this == other); } // dynamically allocates new Bag that won't get deleted const Bag & Bag::operator+(const Bag & other) const { int newsize = capacity + other.capacity; if (newsize > CAPLIMIT) { newsize = sz + other.sz; if (newsize > CAPLIMIT) { cerr << "can't add them together" << endl; return *(new Bag()); } } // Bag temp; // can't return reference to local variable Bag *rptr = new Bag(newsize); rptr->sz = sz + other.sz; int i; for (i = 0; i < sz; i++) rptr->intbag[i] = intbag[i]; for (; i < rptr->sz; i++) rptr->intbag[i] = other.intbag[i - sz]; return *rptr; } // affiliated non-member operators ostream & operator<<(ostream & os, const Bag & b) { return b.write(os); } istream & operator>>(istream & is, Bag & b) { return b.read(is); }