home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-04-21 | 9.2 KB | 360 lines | [TEXT/MPS ] |
- // The C++ Booch Components (Version 2.1)
- // (C) Copyright 1990-1993 Grady Booch. All Rights Reserved.
- //
- // Restricted Rights Legend
- // Use, duplication, or disclosure is subject to restrictions as set forth
- // in subdivision (c)(1)(ii) of the Rights in Technical Data and Computer
- // Software clause at DFARS 252.227-7013.
- //
- // BCDynami.cpp
- //
- // This file contains the definition for the dynamic array-based class
- // used for the representation of dynamic structures.
-
- #include "BCDynami.h"
-
- template<class Item, class StorageManager>
- BC_TDynamic<Item, StorageManager>::BC_TDynamic()
- : fRep(0),
- fSize(0),
- fTotalChunks(0),
- fChunkSize(0),
- fStart(0),
- fStop(0) {}
-
- template<class Item, class StorageManager>
- BC_TDynamic<Item, StorageManager>::BC_TDynamic(BC_Index chunkSize)
- : fRep(0),
- fTotalChunks(0),
- fSize(0),
- fChunkSize(chunkSize),
- fStart(0),
- fStop(0) {}
-
- template<class Item, class StorageManager>
- BC_TDynamic<Item, StorageManager>::
- BC_TDynamic(const BC_TDynamic<Item, StorageManager>& c)
- : fRep(0),
- fTotalChunks(0),
- fSize(0),
- fChunkSize(c.fChunkSize),
- fStart(0),
- fStop(0)
- {
- operator=(c);
- }
-
- template<class Item, class StorageManager>
- BC_TDynamic<Item, StorageManager>::~BC_TDynamic()
- {
- Clear();
- }
-
- template<class Item, class StorageManager>
- BC_TDynamic<Item, StorageManager>&
- BC_TDynamic<Item, StorageManager>::
- operator=(const BC_TDynamic<Item, StorageManager>& c)
- {
- if (this == &c)
- return *this;
- Resize(Length(), c.Length(), 0);
- BC_Index index;
- fSize = c.Length();
- fStart = (fSize) ? 1 : 0;
- fStop = 0;
- if (c.fStart) {
- if (c.fStart <= c.fStop)
- for (index = c.fStart; (index <= c.fStop); index++)
- fRep[fStop++] = c.fRep[index - 1];
- else {
- for (index = c.fStart; (index <= c.fSize); index++)
- fRep[fStop++] = c.fRep[index - 1];
- for (index = 1; (index <= c.fStop); index++)
- fRep[fStop++] = c.fRep[index - 1];
- }
- }
- return *this;
- }
-
- template<class Item, class StorageManager>
- BC_Boolean BC_TDynamic<Item, StorageManager>::
- operator==(const BC_TDynamic<Item, StorageManager>& c) const
- {
- if (this == &c)
- return 1;
- BC_Index count = Length();
- if (count == c.Length()) {
- for (BC_Index index = 0; (index < count); index++)
- if (ItemAt(index) != c.ItemAt(index))
- return 0;
- return 1;
- } else
- return 0;
- }
-
- template<class Item, class StorageManager>
- void BC_TDynamic<Item, StorageManager>::Preallocate(BC_Index newLength)
- {
- BC_Index currentLength = Length();
- if (currentLength < newLength)
- Resize(currentLength, newLength);
- }
-
- template<class Item, class StorageManager>
- void BC_TDynamic<Item, StorageManager>::Clear()
- {
- Resize(0, 0, 0);
- }
-
- template<class Item, class StorageManager>
- void BC_TDynamic<Item, StorageManager>::Insert(const Item& item)
- {
- BC_Index count = Length();
- if (count == fSize)
- Resize(count, count + 1);
- if (!count)
- fStart = fStop = 1;
- else {
- fStart--;
- if (!fStart)
- fStart = fSize;
- }
- fRep[fStart - 1] = item;
- }
-
- template<class Item, class StorageManager>
- void BC_TDynamic<Item, StorageManager>::Insert(const Item& item, BC_Index before)
- {
- BC_Index count = Length();
- BC_Assert((before < count), BC_XRangeError("BC_TDynamic::Insert", BC_kInvalidIndex));
- if (count == fSize)
- Resize(count, count + 1);
- if (!count) {
- fStart = fStop = 1;
- fRep[0] = item;
- } else {
- if (fStart <= fStop) {
- if (before <= (fStop - fStart - before + 1))
- fRep[ExpandLeft(fStart + before - 1)] = item;
- else
- fRep[ExpandRight(fStart + before - 1)] = item;
- } else {
- if (before <= (fSize - fStart))
- fRep[ExpandLeft(fStart + before - 1)] = item;
- else
- fRep[ExpandRight(fStart + before - fSize - 1)] = item;
- }
- }
- }
-
- template<class Item, class StorageManager>
- void BC_TDynamic<Item, StorageManager>::Append(const Item& item)
- {
- BC_Index count = Length();
- if (count == fSize)
- Resize(count, count + 1);
- if (!count)
- fStart = fStop = 1;
- else {
- fStop++;
- if (fStop > fSize)
- fStop = 1;
- }
- fRep[fStop - 1] = item;
- }
-
- template<class Item, class StorageManager>
- void BC_TDynamic<Item, StorageManager>::Append(const Item& item, BC_Index after)
- {
- BC_Index count = Length();
- BC_Assert((after < count),
- BC_XRangeError("BC_TDynamic::Append", BC_kInvalidIndex));
- if (count == fSize)
- Resize(count, count + 1);
- if (!count) {
- fStart = fStop = 1;
- fRep[0] = item;
- } else {
- if (fStart <= fStop) {
- if (after < (fStop - fStart - after))
- fRep[ExpandLeft(fStart + after)] = item;
- else
- fRep[ExpandRight(fStart + after)] = item;
- } else {
- if (after <= (fSize - fStart))
- fRep[ExpandLeft(fStart + after)] = item;
- else
- fRep[ExpandRight(fStart + after - fSize)] = item;
- }
- }
- }
-
- template<class Item, class StorageManager>
- void BC_TDynamic<Item, StorageManager>::Remove(BC_Index at)
- {
- BC_Index count = Length();
- BC_Assert((at < count),
- BC_XRangeError("BC_TDynamic::Remove", BC_kInvalidIndex));
- BC_Assert(count, BC_XUnderflow("BC_TDynamic::Remove", BC_kEmpty));
- if (count == 1)
- fStart = fStop = 0;
- else {
- if (fStart <= fStop) {
- if (at <= (fStop - fStart - at + 1))
- ShrinkLeft(fStart + at - 1);
- else
- ShrinkRight(fStart + at - 1);
- } else {
- if (at <= (fSize - fStart))
- ShrinkLeft(fStart + at - 1);
- else
- ShrinkRight(fStart + at - fSize - 1);
- }
- }
- Resize(count - 1, count - 1);
- }
-
- template<class Item, class StorageManager>
- void BC_TDynamic<Item, StorageManager>::Replace(BC_Index at, const Item& item)
- {
- BC_Assert((at < Length()),
- BC_XRangeError("BC_TDynamic::Replace", BC_kInvalidIndex));
- fRep[at] = item;
- }
-
- template<class Item, class StorageManager>
- BC_Index BC_TDynamic<Item, StorageManager>::Length() const
- {
- if (fStart)
- if (fStart <= fStop)
- return (fStop - fStart + 1);
- else
- return (fSize - fStart + fStop + 1);
- else
- return 0;
- }
-
- template<class Item, class StorageManager>
- const Item& BC_TDynamic<Item, StorageManager>::ItemAt(BC_Index index) const
- {
- index += fStart - 1;
- if ((fStart > fStop) && (index >= fSize))
- index -= fSize;
- return fRep[index];
- }
-
- template<class Item, class StorageManager>
- Item& BC_TDynamic<Item, StorageManager>::ItemAt(BC_Index index)
- {
- index += fStart - 1;
- if ((fStart > fStop) && (index >= fSize))
- index -= fSize;
- return fRep[index];
- }
-
- template<class Item, class StorageManager>
- BC_ExtendedIndex BC_TDynamic<Item, StorageManager>::
- Location(const Item& i, BC_Index start) const
- {
- BC_Index count = Length();
- BC_Assert((start <= count),
- BC_XRangeError("BC_TDynamic::Location", BC_kInvalidIndex));
- for (BC_Index index = start; (index < count); index++)
- if (ItemAt(index) == i)
- return index;
- return -1;
- }
-
- template<class Item, class StorageManager>
- void* BC_TDynamic<Item, StorageManager>::operator new(size_t s)
- {
- return StorageManager::Allocate(s);
- }
-
- template<class Item, class StorageManager>
- void BC_TDynamic<Item, StorageManager>::operator delete(void* p, size_t s)
- {
- StorageManager::Deallocate(p, s);
- }
-
- template<class Item, class StorageManager>
- void BC_TDynamic<Item, StorageManager>::
- Resize(BC_Index currentLength, BC_Index newLength, BC_Boolean preserve)
- {
- BC_Index totalChunks = 0;
- if (newLength)
- totalChunks = (unsigned int)(((newLength - 1) / fChunkSize)) + 1;
- if (fTotalChunks != totalChunks) {
- BC_Index size = totalChunks * fChunkSize;
- Item* newRep =
- (size) ?
- (Item*)(StorageManager::Allocate(size * sizeof(Item))) : 0;
- if (preserve)
- for (BC_Index index = 0; (index < currentLength); index++)
- newRep[index] = ItemAt(index);
- StorageManager::Deallocate(fRep, fSize * sizeof(Item));
- fRep = newRep;
- fSize = size;
- fTotalChunks = totalChunks;
- if (!newLength)
- fStart = fStop = 0;
- else {
- fStart = currentLength ? 1 : 0;
- fStop = currentLength;
- }
- }
- }
-
- template<class Item, class StorageManager>
- BC_Index BC_TDynamic<Item, StorageManager>::ExpandLeft(BC_Index from)
- {
- BC_Index index = --fStart;
- if (!fStart) {
- if (from)
- fRep[fSize - 1] = fRep[0];
- fStart = fSize;
- index++;
- }
- for (; (index < from); index++)
- fRep[index - 1] = fRep[index];
- return (from) ? (from - 1) : (fSize - 1);
- }
-
- template<class Item, class StorageManager>
- BC_Index BC_TDynamic<Item, StorageManager>::ExpandRight(BC_Index from)
- {
- BC_Index index = fStop;
- if (index == fSize) {
- if (from)
- fRep[0] = fRep[fSize - 1];
- fStop = 1;
- index--;
- } else
- fStop++;
- for (; (index > from); index--)
- fRep[index] = fRep[index - 1];
- return (from >= fSize) ? 0 : from;
- }
-
- template<class Item, class StorageManager>
- void BC_TDynamic<Item, StorageManager>::ShrinkLeft(BC_Index from)
- {
- for (BC_Index index = from; (index > (fStart - 1)); index--)
- fRep[index] = fRep[index - 1];
- if (fStart == fSize)
- fStart = 1;
- else
- fStart++;
- }
-
- template<class Item, class StorageManager>
- void BC_TDynamic<Item, StorageManager>::ShrinkRight(BC_Index from)
- {
- for (BC_Index index = from; (index < (fStop - 1)); index++)
- fRep[index] = fRep[index + 1];
- if (fStop == 1)
- fStop = fSize;
- else
- fStop--;
- }
-