0029777: Foundation Classes - The methods of moving of one NCollection_Sequence to...
authormsv <msv@opencascade.com>
Wed, 23 May 2018 07:18:49 +0000 (10:18 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 14 Jun 2018 11:03:04 +0000 (14:03 +0300)
Make the methods Append, Prepend, InsertBefore and InsertAfter, which take another sequence as an argument, copying the sequence instead of joining if the allocators are different.

Add test cases for collection classes.

13 files changed:
src/NCollection/NCollection_List.hxx
src/NCollection/NCollection_Sequence.hxx
src/QANCollection/QANCollection_Test.cxx
tests/collections/n/array1 [new file with mode: 0644]
tests/collections/n/array2 [new file with mode: 0644]
tests/collections/n/arrayMove [new file with mode: 0644]
tests/collections/n/dblmap [new file with mode: 0644]
tests/collections/n/dmap [new file with mode: 0644]
tests/collections/n/idmap [new file with mode: 0644]
tests/collections/n/imap [new file with mode: 0644]
tests/collections/n/list [new file with mode: 0644]
tests/collections/n/seq [new file with mode: 0644]
tests/collections/n/vector [new file with mode: 0644]

index 7ce1eaa..58f0de3 100644 (file)
@@ -274,8 +274,6 @@ public:
     else
     {
       // No - this list has different memory scope
-      Standard_NoSuchObject_Raise_if (!theIter.More(), "NCollection_List::InsertAfter");
-
       Iterator anIter;
       anIter.myPrevious = theIter.myCurrent;
       anIter.myCurrent = theIter.myCurrent->Next();
index 1162164..55ef23b 100644 (file)
@@ -176,14 +176,10 @@ public:
   //! This method does not change the internal allocator.
   NCollection_Sequence& Assign (const NCollection_Sequence& theOther)
   { 
-    if (this == &theOther) 
-      return *this;
-    Clear ();
-    Node * pCur = (Node *) theOther.myFirstItem;
-    while (pCur) {
-      Node* pNew = new (this->myAllocator) Node (pCur->Value());
-      PAppend (pNew);
-      pCur = (Node *) pCur->Next();
+    if (this != &theOther)
+    {
+      Clear();
+      appendSeq((const Node *)theOther.myFirstItem);
     }
     return * this;
   }
@@ -214,8 +210,20 @@ public:
   //! Append another sequence (making it empty)
   void Append (NCollection_Sequence& theSeq)
   {
-    if (myFirstItem == theSeq.myFirstItem) Assign (theSeq);
-    PAppend (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
@@ -225,8 +233,20 @@ public:
   //! Prepend another sequence (making it empty)
   void Prepend (NCollection_Sequence& theSeq)
   {
-    if (myFirstItem == theSeq.myFirstItem) Assign (theSeq);
-    PPrepend (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
@@ -234,7 +254,7 @@ public:
                      const TheItemType&     theItem)
   { InsertAfter (theIndex-1, theItem); }
 
-  //! InsertBefore theIndex another sequence
+  //! InsertBefore theIndex another sequence (making it empty)
   void InsertBefore (const Standard_Integer theIndex,
                      NCollection_Sequence&  theSeq)
   { InsertAfter (theIndex-1, theSeq); }
@@ -244,12 +264,27 @@ public:
                      const TheItemType&     theItem)
   { PInsertAfter (thePosition, new (this->myAllocator) Node (theItem)); }
 
-  //! InsertAfter theIndex theItem
+  //! InsertAfter theIndex another sequence (making it empty)
   void InsertAfter  (const Standard_Integer theIndex,
                      NCollection_Sequence&  theSeq)
-  { PInsertAfter (theIndex, 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 another sequence
+  //! InsertAfter theIndex theItem
   void InsertAfter (const Standard_Integer  theIndex, 
                     const TheItemType&      theItem)
   {
@@ -335,6 +370,31 @@ public:
   // ---------- 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
index 03e10cb..78715b5 100644 (file)
@@ -25,6 +25,7 @@
 #include <Standard_Overflow.hxx>
 
 #include <NCollection_Vector.hxx>
+#include <NCollection_IncAllocator.hxx>
 
 #define ItemType gp_Pnt
 #define Key1Type Standard_Real
@@ -238,6 +239,23 @@ static void TestList (QANCollection_ListFunc&     theL)
   // Assign
   AssignCollection (theL, aL);
 
+  // Different allocators
+  {
+    // The joining of list having different allocator can cause memory error
+    // if the fact of different allocator is not taken into account.
+    Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator;
+    QANCollection_ListFunc aS2(anAlloc);
+    aS2.Append(anItem);
+    theL.Prepend(aS2);
+    aS2.Append(anItem);
+    theL.Append(aS2);
+    aS2.Append(anItem);
+    QANCollection_ListFunc::Iterator anIter(theL);
+    theL.InsertBefore(aS2, anIter);
+    aS2.Append(anItem);
+    theL.InsertAfter(aS2, anIter);
+  }
+
   // Clear
   aL.Clear();
 }
@@ -294,6 +312,22 @@ static void TestSequence (QANCollection_SequenceFunc& theS)
   // Assign
   AssignCollection (theS, aS);
 
+  // Different allocators
+  {
+    // The joining of sequence having different allocator can cause memory error
+    // if the fact of different allocator is not taken into account.
+    Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator;
+    QANCollection_SequenceFunc aS2(anAlloc);
+    aS2.Append(anItem);
+    theS.Prepend(aS2);
+    aS2.Append(anItem);
+    theS.Append(aS2);
+    aS2.Append(anItem);
+    theS.InsertBefore(1, aS2);
+    aS2.Append(anItem);
+    theS.InsertAfter(1, aS2);
+  }
+
   // Clear
   aS.Clear();
 }
@@ -1113,8 +1147,10 @@ void QANCollection::CommandsTest(Draw_Interpretor& theCommands) {
   const char *group = "QANCollection";
 
   // from agvCollTest/src/CollectionEXE/FuncTestEXE.cxx
-  theCommands.Add("QANColTestArray1",         "QANColTestArray1",         __FILE__, QANColTestArray1,         group);  
-  theCommands.Add("QANColTestArray2",         "QANColTestArray2",         __FILE__, QANColTestArray2,         group);  
+  theCommands.Add("QANColTestArray1",         "QANColTestArray1 Lower Upper",
+    __FILE__, QANColTestArray1, group);
+  theCommands.Add("QANColTestArray2",         "QANColTestArray2 LowerRow UpperRow LowerCol UpperCol",
+    __FILE__, QANColTestArray2, group);  
   theCommands.Add("QANColTestMap",            "QANColTestMap",            __FILE__, QANColTestMap,            group);  
   theCommands.Add("QANColTestDataMap",        "QANColTestDataMap",        __FILE__, QANColTestDataMap,        group);  
   theCommands.Add("QANColTestDoubleMap",      "QANColTestDoubleMap",      __FILE__, QANColTestDoubleMap,      group);  
diff --git a/tests/collections/n/array1 b/tests/collections/n/array1
new file mode 100644 (file)
index 0000000..5563982
--- /dev/null
@@ -0,0 +1,3 @@
+puts "Check NCollection_Array1 functionality"
+
+QANColTestArray1 1 10
diff --git a/tests/collections/n/array2 b/tests/collections/n/array2
new file mode 100644 (file)
index 0000000..15a4c83
--- /dev/null
@@ -0,0 +1,3 @@
+puts "Check NCollection_Array2 functionality"
+
+QANColTestArray2 1 5 1 3
diff --git a/tests/collections/n/arrayMove b/tests/collections/n/arrayMove
new file mode 100644 (file)
index 0000000..7b82543
--- /dev/null
@@ -0,0 +1,4 @@
+puts "Check moving of NCollection_Array1 functionality"
+
+puts "REQUIRED ALL: Error at item"
+QANColTestArrayMove
diff --git a/tests/collections/n/dblmap b/tests/collections/n/dblmap
new file mode 100644 (file)
index 0000000..2c13913
--- /dev/null
@@ -0,0 +1,3 @@
+puts "Check NCollection_DoubleMap functionality"
+
+QANColTestDoubleMap
diff --git a/tests/collections/n/dmap b/tests/collections/n/dmap
new file mode 100644 (file)
index 0000000..f08ba46
--- /dev/null
@@ -0,0 +1,3 @@
+puts "Check NCollection_DataMap functionality"
+
+QANColTestDataMap
diff --git a/tests/collections/n/idmap b/tests/collections/n/idmap
new file mode 100644 (file)
index 0000000..901c064
--- /dev/null
@@ -0,0 +1,3 @@
+puts "Check NCollection_IndexedDataMap functionality"
+
+QANColTestIndexedDataMap
diff --git a/tests/collections/n/imap b/tests/collections/n/imap
new file mode 100644 (file)
index 0000000..7059f56
--- /dev/null
@@ -0,0 +1,3 @@
+puts "Check NCollection_IndexedMap functionality"
+
+QANColTestIndexedMap
diff --git a/tests/collections/n/list b/tests/collections/n/list
new file mode 100644 (file)
index 0000000..44f4973
--- /dev/null
@@ -0,0 +1,3 @@
+puts "Check NCollection_List functionality"
+
+QANColTestList
diff --git a/tests/collections/n/seq b/tests/collections/n/seq
new file mode 100644 (file)
index 0000000..9db3fd9
--- /dev/null
@@ -0,0 +1,3 @@
+puts "Check NCollection_Sequence functionality"
+
+QANColTestSequence
diff --git a/tests/collections/n/vector b/tests/collections/n/vector
new file mode 100644 (file)
index 0000000..208fe63
--- /dev/null
@@ -0,0 +1,3 @@
+puts "Check NCollection_Vector functionality"
+
+QANColTestVector