// See the file "COPYING" in the main distribution directory for copyright. #include "config.h" #include #include "Queue.h" BaseQueue::BaseQueue(int size) { const int DEFAULT_CHUNK_SIZE = 10; chunk_size = DEFAULT_CHUNK_SIZE; head = tail = num_entries = 0; if ( size < 0 ) { entry = new ent[1]; max_entries = 0; } else { if ( (entry = new ent[chunk_size+1]) ) max_entries = chunk_size; else { entry = new ent[1]; max_entries = 0; } } } void BaseQueue::push_front(ent a) { if ( num_entries == max_entries ) { resize(max_entries+chunk_size); // make more room chunk_size *= 2; } ++num_entries; if ( head ) entry[--head] = a; else { head = max_entries; entry[head] = a; } } void BaseQueue::push_back(ent a) { if ( num_entries == max_entries ) { resize(max_entries+chunk_size); // make more room chunk_size *= 2; } ++num_entries; if ( tail < max_entries ) entry[tail++] = a; else { entry[tail] = a; tail = 0; } } ent BaseQueue::pop_front() { if ( ! num_entries ) return 0; --num_entries; if ( head < max_entries ) return entry[head++]; else { head = 0; return entry[max_entries]; } } ent BaseQueue::pop_back() { if ( ! num_entries ) return 0; --num_entries; if ( tail ) return entry[--tail]; else { tail = max_entries; return entry[tail]; } } int BaseQueue::resize(int new_size) { if ( new_size < num_entries ) new_size = num_entries; // do not lose any entries if ( new_size != max_entries ) { // Note, allocate extra space, so that we can always // use the [max_entries] element. // ### Yin, why not use realloc()? ent* new_entry = new ent[new_size+1]; if ( new_entry ) { if ( head <= tail ) memcpy( new_entry, entry + head, sizeof(ent) * num_entries ); else { int len = num_entries - tail; memcpy( new_entry, entry + head, sizeof(ent) * len ); memcpy( new_entry + len, entry, sizeof(ent) * tail ); } delete [] entry; entry = new_entry; max_entries = new_size; head = 0; tail = num_entries; } else { // out of memory } } return max_entries; }