List.cp

/*------------------------------------------------------------------------------------------
 
    Program:    CPlusTESample 2.0
    File:       List.cp
    Uses:       List.h
 
    by Andrew Shebanow
    of Apple Macintosh Developer Technical Support
 
    Copyright © 1989-1990 Apple Computer, Inc.
    All rights reserved.
 
------------------------------------------------------------------------------------------*/
 
#ifndef __TYPES__
#include <Types.h>
#endif
#ifndef __MEMORY__
#include <Memory.h>
#endif
#ifndef __ERRORS__
#include <Errors.h>
#endif
 
#ifndef __EXCEPTIONS__
#include "Exceptions.h"
#endif
 
#include "List.h"
 
//----------------------------------------------------------------------------
 
TList::TList()
{
    fObjects = (HandleObjectHandle) NewHandle(sizeof(HandleObjectRef));
 
    fNumObjs = 0;
}
 
void TList::InsertFirst(HandleObject* obj)
{
    long lSize = GetHandleSize((Handle) fObjects);
    SetHandleSize((Handle) fObjects, lSize+sizeof(HandleObjectRef));
    FailMemError();
    // shift list elements downwards
    BlockMove((Ptr) &((*fObjects)[0]),
              (Ptr) &((*fObjects)[1]),
              fNumObjs*sizeof(HandleObjectRef));
 
    (*fObjects)[0] = obj;
    fNumObjs++;
}
 
void TList::InsertLast(HandleObject* obj)
{
    long lSize = GetHandleSize((Handle) fObjects);
    SetHandleSize((Handle) fObjects, lSize+sizeof(HandleObjectRef));
    FailMemError();
    (*fObjects)[fNumObjs] = obj;
    fNumObjs++;
}
 
void TList::MoveToFront(HandleObject* obj)
{
    short i;
 
    // find object in list - return if not present or
    // if object is already at front of list
    if ((i = FindIdx(obj)) <= 0)
      return;
    // shift objects downwards
    BlockMove((Ptr) &((*fObjects)[0]),
              (Ptr) &((*fObjects)[1]),
              (fNumObjs-i-1)*sizeof(HandleObjectRef));
    (*fObjects)[0] = obj;
}
 
void TList::MoveToBack(HandleObject* obj)
{
    short i;
 
    // find object in list - return if not present or
    // if object is already at back of list
    if (((i = FindIdx(obj)) < 0) || (i == fNumObjs - 1))
      return;
    // shift objects upwards
    BlockMove((Ptr) &((*fObjects)[i+1]),
              (Ptr) &((*fObjects)[i]),
              (fNumObjs-i-1)*sizeof(HandleObjectRef));
    (*fObjects)[fNumObjs-1] = obj;
}
 
void TList::MoveFront(HandleObject* obj)
{
    short i;
 
    // find object in list - return if not present or
    // if object is already at front of list
    if ((i = FindIdx(obj)) <= 0)
      return;
    // swap the two objects in the list
    HandleObject* tObj = (*fObjects)[i-1];
    (*fObjects)[i-1] = obj;
    (*fObjects)[i] = tObj;
}
 
void TList::MoveBack(HandleObject* obj)
{
    short i;
 
    // find object in list - return if not present or
    // if object is already at back of list
    if (((i = FindIdx(obj)) < 0) || (i == fNumObjs - 1))
      return;
    // swap the two objects in the list
    HandleObject* tObj = (*fObjects)[i+1];
    (*fObjects)[i+1] = obj;
    (*fObjects)[i] = tObj;
}
 
void TList::Remove(HandleObject* obj)
{
    short i;
 
    // find object in list - return if not present
    if ((i = FindIdx(obj)) < 0)
      return;
    // shift down if not the last element
    if (i < (fNumObjs - 1))
      BlockMove((Ptr) &((*fObjects)[i+1]),
                (Ptr) &((*fObjects)[i]),
                fNumObjs*sizeof(HandleObjectRef));
    fNumObjs--;
    SetHandleSize((Handle) fObjects, fNumObjs*sizeof(HandleObjectRef));
}
 
void TList::RemoveAll()
{
    SetHandleSize((Handle) fObjects,0);
    fNumObjs = 0;
}
 
void TList::Delete(HandleObject* obj)
{
    Remove(obj);
    delete obj;
}
 
void TList::DeleteAll()
{
    // this is kind of strange. We go through the
    // list and delete all the objects BEFORE we
    // actually get rid of the references in the
    // list. This is ok, because we won't ever look at
    // the values again
    for (short i = 0; i < fNumObjs; i++)
      delete (*fObjects)[i];
    RemoveAll();
}
 
HandleObject* TList::At(short idx) const
{
    if ((idx < 0) || (idx > (fNumObjs-1)))
      return nil;
    return (*fObjects)[idx];
}
 
short TList::FindIdx(HandleObject* obj)
{
    for (short i = 0; i < fNumObjs; i++)
      {
        if ((*fObjects)[i] == obj)
          return i;
      }
    return -1;
}
 
//----------------------------------------------------------------------------
 
TListIterator::TListIterator(const TList* ls) : fList(ls)
{
    fIdx = 0;
}