1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-05-01 10:26:12 +03:00
occt/src/PCollection/PCollection_HSequence.gxx
bugmster 973c2be1e1 0024428: Implementation of LGPL license
The copying permission statements at the beginning of source files updated to refer to LGPL.
Copyright dates extended till 2014 in advance.
2013-12-17 12:42:41 +04:00

512 lines
16 KiB
Plaintext

// Created on: 1992-09-24
// Created by: Mireille MERCIEN
// Copyright (c) 1992-1999 Matra Datavision
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and / or modify it
// under the terms of the GNU Lesser General Public version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Standard_NoSuchObject.hxx>
#include <Standard_OutOfRange.hxx>
#include <Standard_NotImplemented.hxx>
#include <Standard_ProgramError.hxx>
#include <Standard_OStream.hxx>
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
// -----------
// 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
}