mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-04 18:06:22 +03:00
Update empty method guards to new style with regex (see PR). Used clang-format 18.1.8. New actions to validate code formatting is added. Update .clang-format with disabling of include sorting. It is temporary changes, then include will be sorted. Apply formatting for /src and /tools folder. The files with .hxx,.cxx,.lxx,.h,.pxx,.hpp,*.cpp extensions.
476 lines
14 KiB
C++
476 lines
14 KiB
C++
// Created on: 2002-03-28
|
|
// Created by: Alexander GRIGORIEV
|
|
// Copyright (c) 2002-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 License 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.
|
|
|
|
#ifndef NCollection_Sequence_HeaderFile
|
|
#define NCollection_Sequence_HeaderFile
|
|
|
|
#include <NCollection_BaseSequence.hxx>
|
|
#include <NCollection_StlIterator.hxx>
|
|
|
|
#include <Standard_OutOfRange.hxx>
|
|
#include <Standard_NoSuchObject.hxx>
|
|
#include <utility>
|
|
|
|
/**
|
|
* Purpose: Definition of a sequence of elements indexed by
|
|
* an Integer in range of 1..n
|
|
*/
|
|
template <class TheItemType>
|
|
class NCollection_Sequence : public NCollection_BaseSequence
|
|
{
|
|
public:
|
|
//! STL-compliant typedef for value type
|
|
typedef TheItemType value_type;
|
|
|
|
public:
|
|
//! Class defining sequence node - for internal use by Sequence
|
|
class Node : public NCollection_SeqNode
|
|
{
|
|
public:
|
|
//! Constructor
|
|
Node(const TheItemType& theItem)
|
|
: NCollection_SeqNode()
|
|
{
|
|
myValue = theItem;
|
|
}
|
|
|
|
//! Constructor
|
|
Node(TheItemType&& theItem)
|
|
: NCollection_SeqNode()
|
|
{
|
|
myValue = std::forward<TheItemType>(theItem);
|
|
}
|
|
|
|
//! Constant value access
|
|
const TheItemType& Value() const { return myValue; }
|
|
|
|
//! Variable value access
|
|
TheItemType& ChangeValue() { return myValue; }
|
|
|
|
private:
|
|
TheItemType myValue;
|
|
}; // End of nested class Node
|
|
|
|
public:
|
|
//! Implementation of the Iterator interface.
|
|
class Iterator : public NCollection_BaseSequence::Iterator
|
|
{
|
|
public:
|
|
//! Empty constructor - for later Init
|
|
Iterator(void) {}
|
|
|
|
//! Constructor with initialisation
|
|
Iterator(const NCollection_Sequence& theSeq, const Standard_Boolean isStart = Standard_True)
|
|
: NCollection_BaseSequence::Iterator(theSeq, isStart)
|
|
{
|
|
}
|
|
|
|
//! Check end
|
|
Standard_Boolean More(void) const { return (myCurrent != NULL); }
|
|
|
|
//! Make step
|
|
void Next(void)
|
|
{
|
|
if (myCurrent)
|
|
{
|
|
myPrevious = myCurrent;
|
|
myCurrent = myCurrent->Next();
|
|
}
|
|
}
|
|
|
|
//! Constant value access
|
|
const TheItemType& Value(void) const { return ((const Node*)myCurrent)->Value(); }
|
|
|
|
//! Variable value access
|
|
TheItemType& ChangeValue(void) const { return ((Node*)myCurrent)->ChangeValue(); }
|
|
|
|
//! Performs comparison of two iterators.
|
|
Standard_Boolean IsEqual(const Iterator& theOther) const
|
|
{
|
|
return myCurrent == theOther.myCurrent;
|
|
}
|
|
}; // End of nested class Iterator
|
|
|
|
//! Shorthand for a regular iterator type.
|
|
typedef NCollection_StlIterator<std::bidirectional_iterator_tag, Iterator, TheItemType, false>
|
|
iterator;
|
|
|
|
//! Shorthand for a constant iterator type.
|
|
typedef NCollection_StlIterator<std::bidirectional_iterator_tag, Iterator, TheItemType, true>
|
|
const_iterator;
|
|
|
|
//! Returns an iterator pointing to the first element in the sequence.
|
|
iterator begin() const { return Iterator(*this, true); }
|
|
|
|
//! Returns an iterator referring to the past-the-end element in the sequence.
|
|
iterator end() const
|
|
{
|
|
Iterator anIter(*this, false);
|
|
anIter.Next();
|
|
return anIter;
|
|
}
|
|
|
|
//! Returns a const iterator pointing to the first element in the sequence.
|
|
const_iterator cbegin() const { return Iterator(*this, true); }
|
|
|
|
//! Returns a const iterator referring to the past-the-end element in the sequence.
|
|
const_iterator cend() const
|
|
{
|
|
Iterator anIter(*this, false);
|
|
anIter.Next();
|
|
return anIter;
|
|
}
|
|
|
|
public:
|
|
// ---------- PUBLIC METHODS ------------
|
|
|
|
//! Empty constructor.
|
|
NCollection_Sequence()
|
|
: NCollection_BaseSequence(Handle(NCollection_BaseAllocator)())
|
|
{
|
|
}
|
|
|
|
//! Constructor
|
|
explicit NCollection_Sequence(const Handle(NCollection_BaseAllocator)& theAllocator)
|
|
: NCollection_BaseSequence(theAllocator)
|
|
{
|
|
}
|
|
|
|
//! Copy constructor
|
|
NCollection_Sequence(const NCollection_Sequence& theOther)
|
|
: NCollection_BaseSequence(theOther.myAllocator)
|
|
{
|
|
appendSeq((const Node*)theOther.myFirstItem);
|
|
}
|
|
|
|
//! Move constructor
|
|
NCollection_Sequence(NCollection_Sequence&& theOther) noexcept
|
|
: NCollection_BaseSequence(theOther.myAllocator)
|
|
{
|
|
this->operator=(std::forward<NCollection_Sequence>(theOther));
|
|
}
|
|
|
|
//! Number of items
|
|
Standard_Integer Size(void) const { return mySize; }
|
|
|
|
//! Number of items
|
|
Standard_Integer Length(void) const { return mySize; }
|
|
|
|
//! Method for consistency with other collections.
|
|
//! @return Lower bound (inclusive) for iteration.
|
|
Standard_Integer Lower() const { return 1; }
|
|
|
|
//! Method for consistency with other collections.
|
|
//! @return Upper bound (inclusive) for iteration.
|
|
Standard_Integer Upper() const { return mySize; }
|
|
|
|
//! Empty query
|
|
Standard_Boolean IsEmpty(void) const { return (mySize == 0); }
|
|
|
|
//! Reverse sequence
|
|
void Reverse(void) { PReverse(); }
|
|
|
|
//! Exchange two members
|
|
void Exchange(const Standard_Integer I, const Standard_Integer J) { PExchange(I, J); }
|
|
|
|
//! Static deleter to be passed to BaseSequence
|
|
static void delNode(NCollection_SeqNode* theNode, Handle(NCollection_BaseAllocator)& theAl)
|
|
{
|
|
((Node*)theNode)->~Node();
|
|
theAl->Free(theNode);
|
|
}
|
|
|
|
//! Clear the items out, take a new allocator if non null
|
|
void Clear(const Handle(NCollection_BaseAllocator)& theAllocator = 0L)
|
|
{
|
|
ClearSeq(delNode);
|
|
if (!theAllocator.IsNull())
|
|
this->myAllocator = theAllocator;
|
|
}
|
|
|
|
//! Replace this sequence by the items of theOther.
|
|
//! This method does not change the internal allocator.
|
|
NCollection_Sequence& Assign(const NCollection_Sequence& theOther)
|
|
{
|
|
if (this != &theOther)
|
|
{
|
|
Clear();
|
|
appendSeq((const Node*)theOther.myFirstItem);
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
//! Replacement operator
|
|
NCollection_Sequence& operator=(const NCollection_Sequence& theOther) { return Assign(theOther); }
|
|
|
|
//! Move operator
|
|
NCollection_Sequence& operator=(NCollection_Sequence&& theOther) noexcept
|
|
{
|
|
if (this == &theOther)
|
|
{
|
|
return *this;
|
|
}
|
|
Clear(theOther.myAllocator);
|
|
myFirstItem = theOther.myFirstItem;
|
|
myLastItem = theOther.myLastItem;
|
|
myCurrentItem = theOther.myCurrentItem;
|
|
myCurrentIndex = theOther.myCurrentIndex;
|
|
mySize = theOther.mySize;
|
|
|
|
theOther.myFirstItem = nullptr;
|
|
theOther.myLastItem = nullptr;
|
|
theOther.myCurrentItem = nullptr;
|
|
theOther.myCurrentIndex = 0;
|
|
theOther.mySize = 0;
|
|
return *this;
|
|
}
|
|
|
|
//! Remove one item
|
|
void Remove(Iterator& thePosition) { RemoveSeq(thePosition, delNode); }
|
|
|
|
//! Remove one item
|
|
void Remove(const Standard_Integer theIndex) { RemoveSeq(theIndex, delNode); }
|
|
|
|
//! Remove range of items
|
|
void Remove(const Standard_Integer theFromIndex, const Standard_Integer theToIndex)
|
|
{
|
|
RemoveSeq(theFromIndex, theToIndex, delNode);
|
|
}
|
|
|
|
//! Append one item
|
|
void Append(const TheItemType& theItem) { PAppend(new (this->myAllocator) Node(theItem)); }
|
|
|
|
//! Append one item
|
|
void Append(TheItemType&& theItem)
|
|
{
|
|
PAppend(new (this->myAllocator) Node(std::forward<TheItemType>(theItem)));
|
|
}
|
|
|
|
//! Append another sequence (making it empty)
|
|
void Append(NCollection_Sequence& theSeq)
|
|
{
|
|
if (this == &theSeq || theSeq.IsEmpty())
|
|
return;
|
|
if (this->myAllocator == theSeq.myAllocator)
|
|
{
|
|
// Then we take the sequence and glue it to our end -
|
|
// deallocation will bring no problem
|
|
PAppend(theSeq);
|
|
}
|
|
else
|
|
{
|
|
// No - this sequence has different memory scope
|
|
appendSeq((const Node*)theSeq.myFirstItem);
|
|
theSeq.Clear();
|
|
}
|
|
}
|
|
|
|
//! Prepend one item
|
|
void Prepend(const TheItemType& theItem) { PPrepend(new (this->myAllocator) Node(theItem)); }
|
|
|
|
//! Prepend one item
|
|
void Prepend(TheItemType&& theItem)
|
|
{
|
|
PPrepend(new (this->myAllocator) Node(std::forward<TheItemType>(theItem)));
|
|
}
|
|
|
|
//! Prepend another sequence (making it empty)
|
|
void Prepend(NCollection_Sequence& theSeq)
|
|
{
|
|
if (this == &theSeq || theSeq.IsEmpty())
|
|
return;
|
|
if (this->myAllocator == theSeq.myAllocator)
|
|
{
|
|
// Then we take the sequence and glue it to our head -
|
|
// deallocation will bring no problem
|
|
PPrepend(theSeq);
|
|
}
|
|
else
|
|
{
|
|
// No - this sequence has different memory scope
|
|
prependSeq((const Node*)theSeq.myFirstItem, 1);
|
|
theSeq.Clear();
|
|
}
|
|
}
|
|
|
|
//! InsertBefore theIndex theItem
|
|
void InsertBefore(const Standard_Integer theIndex, const TheItemType& theItem)
|
|
{
|
|
InsertAfter(theIndex - 1, theItem);
|
|
}
|
|
|
|
//! InsertBefore theIndex theItem
|
|
void InsertBefore(const Standard_Integer theIndex, TheItemType&& theItem)
|
|
{
|
|
InsertAfter(theIndex - 1, theItem);
|
|
}
|
|
|
|
//! InsertBefore theIndex another sequence (making it empty)
|
|
void InsertBefore(const Standard_Integer theIndex, NCollection_Sequence& theSeq)
|
|
{
|
|
InsertAfter(theIndex - 1, theSeq);
|
|
}
|
|
|
|
//! InsertAfter the position of iterator
|
|
void InsertAfter(Iterator& thePosition, const TheItemType& theItem)
|
|
{
|
|
PInsertAfter(thePosition, new (this->myAllocator) Node(theItem));
|
|
}
|
|
|
|
//! InsertAfter the position of iterator
|
|
void InsertAfter(Iterator& thePosition, TheItemType&& theItem)
|
|
{
|
|
PInsertAfter(thePosition, new (this->myAllocator) Node(theItem));
|
|
}
|
|
|
|
//! InsertAfter theIndex another sequence (making it empty)
|
|
void InsertAfter(const Standard_Integer theIndex, NCollection_Sequence& theSeq)
|
|
{
|
|
if (this == &theSeq || theSeq.IsEmpty())
|
|
return;
|
|
if (this->myAllocator == theSeq.myAllocator)
|
|
{
|
|
// Then we take the list and glue it to our head -
|
|
// deallocation will bring no problem
|
|
PInsertAfter(theIndex, theSeq);
|
|
}
|
|
else
|
|
{
|
|
// No - this sequence has different memory scope
|
|
prependSeq((const Node*)theSeq.myFirstItem, theIndex + 1);
|
|
theSeq.Clear();
|
|
}
|
|
}
|
|
|
|
//! InsertAfter theIndex theItem
|
|
void InsertAfter(const Standard_Integer theIndex, const TheItemType& theItem)
|
|
{
|
|
Standard_OutOfRange_Raise_if(theIndex < 0 || theIndex > mySize,
|
|
"NCollection_Sequence::InsertAfter");
|
|
PInsertAfter(theIndex, new (this->myAllocator) Node(theItem));
|
|
}
|
|
|
|
//! InsertAfter theIndex theItem
|
|
void InsertAfter(const Standard_Integer theIndex, TheItemType&& theItem)
|
|
{
|
|
Standard_OutOfRange_Raise_if(theIndex < 0 || theIndex > mySize,
|
|
"NCollection_Sequence::InsertAfter");
|
|
PInsertAfter(theIndex, new (this->myAllocator) Node(theItem));
|
|
}
|
|
|
|
//! Split in two sequences
|
|
void Split(const Standard_Integer theIndex, NCollection_Sequence& theSeq)
|
|
{
|
|
theSeq.Clear(this->myAllocator);
|
|
PSplit(theIndex, theSeq);
|
|
}
|
|
|
|
//! First item access
|
|
const TheItemType& First() const
|
|
{
|
|
Standard_NoSuchObject_Raise_if(mySize == 0, "NCollection_Sequence::First");
|
|
return ((const Node*)myFirstItem)->Value();
|
|
}
|
|
|
|
//! First item access
|
|
TheItemType& ChangeFirst()
|
|
{
|
|
Standard_NoSuchObject_Raise_if(mySize == 0, "NCollection_Sequence::ChangeFirst");
|
|
return ((Node*)myFirstItem)->ChangeValue();
|
|
}
|
|
|
|
//! Last item access
|
|
const TheItemType& Last() const
|
|
{
|
|
Standard_NoSuchObject_Raise_if(mySize == 0, "NCollection_Sequence::Last");
|
|
return ((const Node*)myLastItem)->Value();
|
|
}
|
|
|
|
//! Last item access
|
|
TheItemType& ChangeLast()
|
|
{
|
|
Standard_NoSuchObject_Raise_if(mySize == 0, "NCollection_Sequence::ChangeLast");
|
|
return ((Node*)myLastItem)->ChangeValue();
|
|
}
|
|
|
|
//! Constant item access by theIndex
|
|
const TheItemType& Value(const Standard_Integer theIndex) const
|
|
{
|
|
Standard_OutOfRange_Raise_if(theIndex <= 0 || theIndex > mySize, "NCollection_Sequence::Value");
|
|
|
|
NCollection_Sequence* const aLocalTHIS = (NCollection_Sequence*)this;
|
|
aLocalTHIS->myCurrentItem = Find(theIndex);
|
|
aLocalTHIS->myCurrentIndex = theIndex;
|
|
return ((const Node*)myCurrentItem)->Value();
|
|
}
|
|
|
|
//! Constant operator()
|
|
const TheItemType& operator()(const Standard_Integer theIndex) const { return Value(theIndex); }
|
|
|
|
//! Variable item access by theIndex
|
|
TheItemType& ChangeValue(const Standard_Integer theIndex)
|
|
{
|
|
Standard_OutOfRange_Raise_if(theIndex <= 0 || theIndex > mySize,
|
|
"NCollection_Sequence::ChangeValue");
|
|
|
|
myCurrentItem = Find(theIndex);
|
|
myCurrentIndex = theIndex;
|
|
return ((Node*)myCurrentItem)->ChangeValue();
|
|
}
|
|
|
|
//! Variable operator()
|
|
TheItemType& operator()(const Standard_Integer theIndex) { return ChangeValue(theIndex); }
|
|
|
|
//! Set item value by theIndex
|
|
void SetValue(const Standard_Integer theIndex, const TheItemType& theItem)
|
|
{
|
|
ChangeValue(theIndex) = theItem;
|
|
}
|
|
|
|
// ******** Destructor - clears the Sequence
|
|
virtual ~NCollection_Sequence(void) { Clear(); }
|
|
|
|
private:
|
|
// ---------- FRIEND CLASSES ------------
|
|
friend class Iterator;
|
|
|
|
// ----------- PRIVATE METHODS -----------
|
|
|
|
//! append the sequence headed by the given Node
|
|
void appendSeq(const Node* pCur)
|
|
{
|
|
while (pCur)
|
|
{
|
|
Node* pNew = new (this->myAllocator) Node(pCur->Value());
|
|
PAppend(pNew);
|
|
pCur = (const Node*)pCur->Next();
|
|
}
|
|
}
|
|
|
|
//! insert the sequence headed by the given Node before the item with the given index
|
|
void prependSeq(const Node* pCur, Standard_Integer ind)
|
|
{
|
|
ind--;
|
|
while (pCur)
|
|
{
|
|
Node* pNew = new (this->myAllocator) Node(pCur->Value());
|
|
PInsertAfter(ind++, pNew);
|
|
pCur = (const Node*)pCur->Next();
|
|
}
|
|
}
|
|
};
|
|
|
|
#endif
|