#include #include #include #include #include // ---------------------------------------------------------------------- // Copyright: Matra-Datavision 1992 // File: PCollection_HSequence.gxx // Created: Sep, 24 1992 // Author: Mireille MERCIEN // ---------------------------------------------------------------------- // ----------- // constructor : // ----------- PCollection_HSequence::PCollection_HSequence() { Size = 0; FirstItem.Nullify(); LastItem.Nullify(); } // ---------------------------------- // Clear : Clear the Current Sequence // ---------------------------------- void PCollection_HSequence::Clear() { Handle(PCollection_SeqNode) cell; Handle(PCollection_SeqNode) pnul; pnul.Nullify(); if (Size != 0) { while (Size != 1) { cell = FirstItem; FirstItem = FirstItem->Next(); FirstItem->SetPrevious(pnul); #ifndef CSFDB cell.Delete(); #endif --Size; } FirstItem.Nullify(); #ifndef CSFDB LastItem.Delete(); // free memory #endif Size = 0; } } // ------------------------------------------------- // Append : Push an item at the end of the sequence // ------------------------------------------------- void PCollection_HSequence::Append(const Item& T) { Handle(PCollection_SeqNode) newcell; #ifndef OBJS newcell = new PCollection_SeqNode(LastItem,T); #else newcell = new (os_segment::of(this)) PCollection_SeqNode(LastItem,T); #endif if (Size == 0) FirstItem = newcell; if (!LastItem.IsNull()) LastItem->SetNext(newcell); LastItem = newcell; ++Size; } // --------------------------------------------------- // Append : Push a sequence at the end of the sequence // --------------------------------------------------- void PCollection_HSequence::Append(const Handle(PCollection_HSequence)& S) { for (Standard_Integer i = 1; i <= S->Length(); i++) Append (S->Value(i)); } // --------------------------------------------------------- // Prepend : Push an element at the begining of the sequence // --------------------------------------------------------- void PCollection_HSequence::Prepend(const Item& T) { Handle(PCollection_SeqNode) newcell; #ifndef OBJS newcell = new PCollection_SeqNode(T,FirstItem); #else newcell = new (os_segment::of(this)) PCollection_SeqNode(T,FirstItem); #endif if (Size == 0) LastItem = newcell; if (!FirstItem.IsNull()) FirstItem->SetPrevious(newcell); FirstItem = newcell; ++Size; } // --------------------------------------------------------- // Prepend : Push a sequence at the begining of the sequence // --------------------------------------------------------- void PCollection_HSequence::Prepend(const Handle (PCollection_HSequence)& S) { for (Standard_Integer i = S->Length(); i >= 1; i--) Prepend (S->Value(i)); } // --------------------------------------------------------- // Reverse : Reverse the order of a given sequence // --------------------------------------------------------- void PCollection_HSequence::Reverse() { if (Size == 0 || Size == 1) return; Handle(PCollection_SeqNode) back,next,temp; temp = LastItem; while (!temp.IsNull()) { back = temp->Previous(); next = temp->Next(); temp->SetNext(back); temp->SetPrevious(next); temp = temp->Next(); } temp = FirstItem; FirstItem = LastItem; LastItem = temp; } // ------------------------------------------------------------------- // InsertBefore : Insert an item before a given index in the sequence // -------------------------------------------------------------------- void PCollection_HSequence::InsertBefore(const Standard_Integer Index, const Item& T) { if ( Index <= 0 || Index > Length() ) Standard_OutOfRange::Raise(); if ( Index == 1 ) { Prepend (T); return; } //Index research Standard_Integer i = 1; Handle(PCollection_SeqNode) cell = FirstItem; while (i != Index) { cell = cell->Next(); ++i; } // Insertion before Index Handle(PCollection_SeqNode) previous = cell->Previous(); #ifndef OBJS Handle(PCollection_SeqNode) temp = new PCollection_SeqNode(previous,cell,T); #else Handle(PCollection_SeqNode) temp = new (os_segment::of(this)) PCollection_SeqNode(previous,cell,T); #endif previous->SetNext(temp); cell->SetPrevious(temp); ++Size; } // ---------------------------------------------------------------------- // InsertBefore : Insert a sequence before a specific index in a sequence // ---------------------------------------------------------------------- void PCollection_HSequence::InsertBefore(const Standard_Integer Index , const Handle(PCollection_HSequence)& S) { if ( Index <= 0 || Index > Size ) Standard_OutOfRange::Raise(); for (Standard_Integer i = 1, j = Index ; i <= S->Length(); i++,j++) InsertBefore(j,S->Value(i)); } // ----------------------------------------------------------------- // InsertAfter : Insert an element after a given index in a sequence // ----------------------------------------------------------------- void PCollection_HSequence::InsertAfter(const Standard_Integer Index, const Item& T) { if ( Index <= 0 || Index > Length() ) Standard_OutOfRange::Raise(); if ( Index == Size ) Append (T); else InsertBefore (Index+1,T); } // ------------------------------------------------------------------- // InsertAfter : Insert a sequence after a given index in the sequence // ------------------------------------------------------------------- void PCollection_HSequence::InsertAfter(const Standard_Integer Index, const Handle(PCollection_HSequence)&S) { if ( Index <= 0 || Index > Length() ) Standard_OutOfRange::Raise(); for (Standard_Integer i = 1, j = Index ; i <= S->Length(); i++,j++) InsertAfter (j,S->Value(i)); } // ---------------------------------------- // Exchange : Exchange two elements in the sequence // ---------------------------------------- void PCollection_HSequence::Exchange(const Standard_Integer I, const Standard_Integer J) { if ( I <= 0 || J <= 0 || I > Length() || J > Length() ) Standard_OutOfRange::Raise(); Item T = Value(J); SetValue(J,Value(I)); SetValue(I,T); } // ---------------------------------------------------- // SubSequence : Returns a sub-sequence from a sequence // ---------------------------------------------------- Handle(PCollection_HSequence) PCollection_HSequence::SubSequence (const Standard_Integer From,const Standard_Integer To) const { if ( From <= 0 || From > Length() || To <= 0 || To > Length() || To < From ) Standard_OutOfRange::Raise(); #ifndef OBJS Handle (PCollection_HSequence) SubSeq = new PCollection_HSequence; #else Handle (PCollection_HSequence) SubSeq = new (os_segment::of(this)) PCollection_HSequence; #endif for(Standard_Integer i = From ; i <= To; i++) SubSeq->Append(Value(i)); return SubSeq; } // --------------------------------------------- // Split : Split a sequence in two sub-sequences // --------------------------------------------- Handle (PCollection_HSequence) PCollection_HSequence::Split(const Standard_Integer Index) { Standard_Integer i ; if ( Index <= 0 || Index > Length() ) Standard_OutOfRange::Raise(); // construct the new sequence #ifndef OBJS Handle(PCollection_HSequence) Seq = new PCollection_HSequence; #else Handle(PCollection_HSequence) Seq = new (os_segment::of(this)) PCollection_HSequence; #endif for (i = Index ; i<= Size; i++) Seq->Append(Value(i)); // Update the old sequence if (Index == 1 ) { Clear(); return Seq; } // Index research i = 1; Handle(PCollection_SeqNode) cell = FirstItem; while (i != Index-1) { cell = cell->Next(); ++i; } // Re-build the Sequence Handle(PCollection_SeqNode) pnul; pnul.Nullify(); LastItem = cell; LastItem->SetNext(pnul); Size = Index - 1 ; return Seq; } // ---------------------------------------------------------- // SetValue : Change the element of a given index in a sequence // ---------------------------------------------------------- void PCollection_HSequence::SetValue(const Standard_Integer Index, const Item& T) { if (Index <= 0 || Index > Length()) Standard_OutOfRange::Raise(); // Index research Standard_Integer i = 1; Handle(PCollection_SeqNode) cell = FirstItem; while (i != Index ) { cell = cell->Next(); ++i; } // Change the value of the node cell->SetValue(T); } // ----------------------------------------- // Value : Return the value of a given index // ----------------------------------------- Item PCollection_HSequence::Value(const Standard_Integer Index) const { if (Index <= 0 || Index > Length()) Standard_OutOfRange::Raise(); // Index research Standard_Integer i = 1; Handle(PCollection_SeqNode) cell = FirstItem; while (i != Index ) { cell = cell->Next(); ++i; } // returns the value of the node return cell->Value(); } // ---------------------------------------------------------------- // Contains : Returns True if the sequence contains a given element // ---------------------------------------------------------------- //Standard_Boolean PCollection_HSequence::Contains(const Item& T) const Standard_Boolean PCollection_HSequence::Contains(const Item& ) const { Standard_ProgramError::Raise("PCollection_HSequence::Contains : Obsolete method..."); return Standard_False; } // ------------------------------------------------------------- // Location : returns the index of the nth occurence of an item. // ------------------------------------------------------------- //Standard_Integer PCollection_HSequence::Location(const Standard_Integer N, // const Item& T, // const Standard_Integer From, // const Standard_Integer To) const Standard_Integer PCollection_HSequence::Location(const Standard_Integer , const Item& , const Standard_Integer , const Standard_Integer ) const { Standard_ProgramError::Raise("PCollection_HSequence::Location : Obsolete method..."); return 0; } // ------------------------------------------------------------- // Location : returns the index of the nth occurence of an item. // ------------------------------------------------------------- //Standard_Integer PCollection_HSequence:: // Location(const Standard_Integer N,const Item& T) const Standard_Integer PCollection_HSequence:: Location(const Standard_Integer ,const Item& ) const { Standard_ProgramError::Raise("PCollection_HSequence::Location : Obsolete method..."); return 0; } // ------------------------------------- // Remove : Remove an item in a sequence // ------------------------------------- void PCollection_HSequence::Remove(const Standard_Integer Index) { if (Index <= 0 || Index > Size ) Standard_OutOfRange::Raise(); if (Size == 1) { Size = 0; FirstItem.Nullify(); #ifndef CSFDB LastItem.Delete(); // free memory #endif } else { Handle(PCollection_SeqNode) pnul,cell,previous,next; pnul.Nullify(); if ( Index == 1 ) { // Remove the first Index cell = FirstItem; FirstItem = FirstItem->Next(); FirstItem->SetPrevious(pnul); #ifndef CSFDB cell.Delete(); // free memory #endif --Size; } else if ( Index == Size ) { // Remove the last Index cell = LastItem; LastItem = LastItem->Previous(); LastItem->SetNext(pnul); #ifndef CSFDB cell.Delete(); // free memory #endif --Size; } else { Standard_Integer i = 1; cell = FirstItem; while (i != Index) { cell = cell->Next(); ++i; } previous = cell->Previous(); next = cell->Next(); previous->SetNext(next); next->SetPrevious(previous); #ifndef CSFDB cell.Delete(); // free memory #endif --Size; } } } // --------------------- // Remove a set of items // --------------------- void PCollection_HSequence::Remove(const Standard_Integer From,const Standard_Integer To) { if (From <= 0 || From > Size || To <= 0 || To > Size || From > To ) Standard_OutOfRange::Raise(); for (Standard_Integer i = From; i<= To; i++) Remove(From); } // --------------------------------------------------- // First : Returns the first element of the sequence // Raises an exeption if the sequence is empty // ---------------------------------------------------- Item PCollection_HSequence::First() const { if (Size == 0) Standard_NoSuchObject::Raise(); return FirstItem->Value(); } // ---------------------------------------------------- // Last : Returns the last element of the sequence // Raises an exeption if the sequence is empty // ---------------------------------------------------- Item PCollection_HSequence::Last() const { if (Size == 0) Standard_NoSuchObject::Raise(); return LastItem->Value(); } // ---------------------------------------------------- // // ShallowCopy // // ---------------------------------------------------- Handle(Standard_Persistent) PCollection_HSequence::ShallowCopy() const { Handle (PCollection_HSequence) TheCopy ; Handle (PCollection_SeqNode) TheList ; #ifndef OBJS TheCopy = new PCollection_HSequence; #else TheCopy = new (os_segment::of(this)) PCollection_HSequence; #endif TheList = FirstItem; for (Standard_Integer I = 1; I <= Size; I++) { TheCopy->Append(TheList->Value()); TheList = TheList->Next(); } return TheCopy; } // ---------------------------------------------------- // // ShallowDump // ---------------------------------------------------- void PCollection_HSequence::ShallowDump(Standard_OStream& S) const { S << "begin class Sequence "<< endl; S << "Size : "<< Size << "element(s)." << endl; Standard_Integer i = 1; Handle(PCollection_SeqNode) cell = FirstItem; while ( !cell.IsNull() ) { S << "Index : "<< i << endl; // ::ShallowDump(cell->Value(),S); cell = cell->Next(); ++i; } S << "end class Sequence" << endl; } // IsEmpty : Returns Standard_True if the sequence is empty (i.e. Size = 0) Standard_Boolean PCollection_HSequence::IsEmpty() const { return (Size == 0); } // Length : Returns the length of the sequence Standard_Integer PCollection_HSequence::Length() const { return Size; } // GetFirst : Returns the field "FirstItem" Handle(PCollection_SeqNode) PCollection_HSequence::GetFirst() const { return FirstItem; } // GetLast : Returns the field "LastItem" Handle(PCollection_SeqNode) PCollection_HSequence::GetLast() const { return LastItem; } void PCollection_HSequence::Destroy() { #ifdef CSFDB Clear(); #endif }