#if !defined _Already_defined_tuple #define _Already_defined_tuple #include #include #include #include namespace omega { template class Tuple_Iterator; // TUPLES ARE INDEXED STARTING AT 1 // index\(i\) == 0 MEANS i IS NOT IN THE TUPLE template class Tuple : public Sequence { public: Tuple(); Tuple(int size); Tuple (const Tuple& tpl); virtual ~Tuple(); Tuple& operator=(const Tuple& tpl); int size() const { return sz; } int length() const { return sz; } bool operator==(const Tuple &b) const; void reallocate(const int); void delete_last(); void append(const Tuple &v); void append(const T &v); void join(Tuple &v); void clear(); int empty() const; Iterator *new_iterator(); virtual T &operator[](int index); virtual const T &operator[](int index) const; int index(const T &) const; friend class Tuple_Iterator; private: int prealloc_size(const int req_size) { return max(req_size+prealloc_pad,prealloc_min); } int realloc_size(const int oldsize) { return 2*oldsize; } int sz, alloc_sz; // Number of elements, size of allocated array int prealloc_min,prealloc_pad; // These should be static, but that // causes portability prob. for initialization protected: T * data; }; template class Tuple_Iterator : public Iterator { public: Tuple_Iterator(const Tuple &tpl); const T & operator*() const; T & operator*(); void set_position(const int req_pos); void operator++(int); void operator++(); void operator--(int); void operator--(); void set_to_last(); void set_to_first(); // void set_position(const int req_pos); Don't do this, compiler bug bool live() const; Iterator *new_copy() const; private: Tuple_Iterator(T * cr, T * frst, T *lst, int insz); T * current, * lastptr, *firstptr; int sz; }; } // namespace #define instantiate_Tuple(T) template class Tuple; \ template class Tuple_Iterator; \ instantiate_Sequence(T) namespace omega { template T &Tuple::operator[](int index) { assert(1 <= index && index <= sz); return data[index-1]; } template const T &Tuple::operator[](int index) const { assert(1 <= index && index <= sz); return data[index-1]; } template Tuple::~Tuple() { if (data) delete [] data; } template Tuple::Tuple() : sz(0), alloc_sz(0), prealloc_min(20),prealloc_pad(5), data(0) { // nothing needs be done } template Tuple::Tuple(int size) : sz(size), prealloc_min(20),prealloc_pad(5) { if (sz > 0) { alloc_sz = prealloc_size(sz); data = new T[alloc_sz]; assert(alloc_sz >= sz); //Need some handling for out of memory. assert (data!=0); } else { alloc_sz = 0; data = 0; } } template Tuple::Tuple(const Tuple& t) : sz(t.sz), alloc_sz(t.alloc_sz), prealloc_min(20),prealloc_pad(5) { if (sz > 0) { data = new T[alloc_sz]; assert (data!=0); assert (alloc_sz >= sz); for (int i=0; i Tuple& Tuple::operator=(const Tuple& t) { if (this != &t) { // Delete this if (data) delete [] data; sz = t.sz; alloc_sz = t.alloc_sz; assert(alloc_sz >= sz); if (sz > 0) { // Copy old data = new T[alloc_sz]; assert (data!=0); for (int i=0; i void Tuple::reallocate(const int req_size) { if (alloc_sz >= req_size) { // if (sz >= req_size), does this. sz = req_size; return; } alloc_sz = prealloc_size(req_size); T* tmp_data = new T[alloc_sz]; for(int i=0;i= req_size); } template void Tuple::delete_last() { assert(sz > 0); sz --; } template void Tuple::append(const T &v) { // Check if reallocation is necessary. if (sz == 0) { // Empty Tuple assert(alloc_sz >= 0); // May be nonzero for cleared tuple if(alloc_sz == 0) { // If it's > 1 no allocation is necessary alloc_sz = prealloc_size(1); data = new T[alloc_sz]; } assert (alloc_sz > 0 && data != 0); } else { if(sz == alloc_sz) { // Requires new allocation alloc_sz = realloc_size(alloc_sz); T * data_tmp = new T[alloc_sz]; assert (data_tmp!=0); assert (alloc_sz > sz); for (int i=0; i= sz); data[sz++] = v; } template void Tuple::append(const Tuple& t) { int old_sz = sz; reallocate(t.size()+size()); assert(alloc_sz >= sz); for(int i=0; i void Tuple::join(Tuple& t) { int old_sz = sz; reallocate(t.size()+size()); assert(alloc_sz >= sz); for(int i=0; i void Tuple::clear() { if (sz) delete [] data; data = 0; alloc_sz = 0; sz = 0; } template int Tuple::empty() const { return (sz == 0); } template Iterator *Tuple::new_iterator() { return new Tuple_Iterator(*this); } template int Tuple::index(const T & var) const /* returns index or 0 if var isn't in the tuple */ { int i; for (i=0; i bool Tuple::operator == (const Tuple& b) const { int i; if (sz != b.size()) return false; for (i=0; i Tuple_Iterator::Tuple_Iterator(const Tuple &tpl) : current(tpl.data), lastptr(tpl.data+tpl.sz-1), firstptr(tpl.data), sz(tpl.sz) { } template Tuple_Iterator::Tuple_Iterator(T * cr, T *frst, T * lst, int insz) : current(cr), lastptr(lst), firstptr(frst), sz(insz) { } template const T & Tuple_Iterator::operator*() const { assert (current<=lastptr && current>=firstptr); return *current; } template T & Tuple_Iterator::operator*() { assert (current<=lastptr && current >=firstptr); return *current; } template void Tuple_Iterator::operator++(int) { current++; } template void Tuple_Iterator::operator++() { current++; } template void Tuple_Iterator::operator--(int) { current--; } template void Tuple_Iterator::operator--() { current--; } template void Tuple_Iterator::set_to_last() { current = lastptr; } template void Tuple_Iterator::set_to_first() { current = firstptr; } template void Tuple_Iterator::set_position(const int req_pos) { assert(req_pos <= sz && 1 <= req_pos); current = firstptr + (req_pos - 1); } template bool Tuple_Iterator::live() const { return (current !=0 && current<=lastptr && current >= firstptr); } template Iterator *Tuple_Iterator::new_copy() const { return new Tuple_Iterator(current, firstptr, lastptr, sz); } } // namespace #endif