#include #include "list.h" // Use memberwise initialization to set the size and initial cursor // position. Until we actually have something in the array, it's illegal // to have cursor >= 0. // // Note that we don't initialize the elements of the item array. Since // the array is private, we can completely control access to it. And // because we're implementing the class, we can guarantee that nobody // will read a slot in the array that doesn't hold a valid int. So // it's safe. IntList::IntList() : size( 0 ) , cursor( -1 ) {} // Call getSize() here instead of reading the size field directly. Why? // Because you might decide that getSize() needs to do something fancy, // like print a message. You want this to be an 'official' usage of // getSize(). bool IntList::isEmpty() { return getSize() == 0; } bool IntList::isFull() { return getSize() == MAX_LIST_LENGTH; } int IntList::getSize() { return size; } // You might be tempted to change this method to // // void IntList::start() // { // assert( !isEmpty() ); // cursor = 0; // } // // The reason why I use an if instead is that I allow you // to _try_ to walk through the empty list, it just won't // do anything. You'll just be at the end immediately. // There are many times in programming where you don't know // how many items you're dealing with, and that number may // be zero. It's nice to be able to treat an empty collection // in the same way as a non-empty one. void IntList::start() { if( !isEmpty() ) { cursor = 0; } } // However, it _is_ illegal to walk past the end of a list. // This is fair because you should always check atEnd() before // you call advance(). void IntList::advance() { assert( !atEnd() ); cursor++; } // Check for isEmpty() so that the cursor in empty list will always // be at the end of the list. bool IntList::atEnd() { return isEmpty() || cursor >= size; } int IntList::getData() { return items[ cursor ]; } // Need a special case if the list is empty to allow us to get // started. If the list is empty, put the item in the zeroeth // position. void IntList::insertBefore( int item ) { if( cursor == -1 ) { placeAtStart( item ); } else { assert( cursor >= 0 && cursor < size ); makeRoom( cursor ); items[ cursor ] = item; } } // Special case here too. void IntList::insertAfter( int item ) { if( cursor == -1 ) { placeAtStart( item ); } else { assert( cursor >= 0 && cursor < size ); makeRoom( cursor + 1 ); items[ cursor + 1 ] = item; ++cursor; } } void IntList::deleteItem() { assert( cursor >= 0 && cursor < size ); for( int idx = cursor; idx < size; idx++ ) { items[ idx ] = items[ idx + 1 ]; } --size; // Once we've removed an element, we need to reposition // the cursor in an intelligent way. if( isEmpty() ) { cursor = -1; } } void IntList::makeRoom( int position ) { assert( !isFull() ); for( int idx = size - 1; idx >= position; --idx ) { items[ idx + 1 ] = items[ idx ]; } ++size; } void IntList::placeAtStart( int item ) { cursor = 0; items[ 0 ] = item; size = 1; }