Salome HOME
Fix bug in test on 24 cores CPU test
[modules/kernel.git] / src / SALOMEDSImpl / SALOMEDSImpl_AttributeTableOfReal.cxx
index 2c3aba89e3ef811ed4d59cd737efaad6c69d0e8f..ab0fee33093113bdb54f3d0da716e28dbf6ee14b 100644 (file)
@@ -1,51 +1,49 @@
-// Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// Copyright (C) 2007-2021  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-// 
+//
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either 
-// version 2.1 of the License.
-// 
-// This library is distributed in the hope that it will be useful 
-// but WITHOUT ANY WARRANTY; without even the implied warranty of 
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 // Lesser General Public License for more details.
 //
-// You should have received a copy of the GNU Lesser General Public  
-// License along with this library; if not, write to the Free Software 
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  File   : SALOMEDSImpl_AttributeTableOfReal.cxx
 //  Author : Michael Ponikarov
 //  Module : SALOME
-
+//
 #include "SALOMEDSImpl_AttributeTableOfReal.hxx"
-#include <stdio.h>
-#include <strstream>
 
-using namespace std;
+#include <sstream>
+#include <algorithm>
 
 #define SEPARATOR '\1'
+typedef std::map<int, double>::const_iterator MI;
 
-typedef map<int, double>::const_iterator MI;
-
-static std::string getUnit(std::string theString)
+static std::string getUnit(const std::string& theString)
 {
   std::string aString(theString);
-  int aPos = aString.find(SEPARATOR);
-  if(aPos <= 0 || aPos == aString.size() ) return std::string();
-  return aString.substr(aPos+1, aString.size());
+  size_t aPos = aString.find(SEPARATOR);
+  return aPos >= aString.size()-1 ? std::string() : aString.substr(aPos+1);
 }
 
-static std::string getTitle(std::string theString)
+static std::string getTitle(const std::string& theString)
 {
   std::string aString(theString);
-  int aPos = aString.find(SEPARATOR);
-  if(aPos < 0) return aString;
-  if(aPos == 0) return std::string();
-  return aString.substr(0, aPos);
+  size_t aPos = aString.find(SEPARATOR);
+  return aPos == std::string::npos ? aString : aString.substr(0, aPos);
 }
 
 const std::string& SALOMEDSImpl_AttributeTableOfReal::GetID() 
@@ -76,7 +74,7 @@ void SALOMEDSImpl_AttributeTableOfReal::SetNbColumns(const int theNbColumns)
   CheckLocked();  
   Backup();
   
-  map<int, double> aMap;
+  std::map<int, double> aMap;
   aMap = myTable;
   myTable.clear();
 
@@ -91,8 +89,8 @@ void SALOMEDSImpl_AttributeTableOfReal::SetNbColumns(const int theNbColumns)
 
   myNbColumns = theNbColumns;
 
-  while (myCols.size() < myNbColumns) { // append empty columns titles
-    myCols.push_back(string(""));
+  while ((int)myCols.size() < myNbColumns) { // append empty columns titles
+    myCols.push_back(std::string(""));
   }
   
   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
@@ -113,20 +111,20 @@ std::string SALOMEDSImpl_AttributeTableOfReal::GetTitle() const
 }
 
 void SALOMEDSImpl_AttributeTableOfReal::SetRowData(const int theRow,
-                                                  const vector<double>& theData) 
+                                                   const std::vector<double>& theData) 
 {
   CheckLocked();  
-  if(theData.size() > myNbColumns) SetNbColumns(theData.size());
+  if((int)theData.size() > myNbColumns) SetNbColumns((int)theData.size()); //!< TODO: conversion from size_t to const int, possible loss of data
 
   Backup();
 
-  while (myRows.size() < theRow) { // append new row titles
+  while ((int)myRows.size() < theRow) { // append new row titles
     myRows.push_back(std::string(""));
   }
 
-  int i, aShift = (theRow-1)*myNbColumns, aLength = theData.size();
+  size_t i, aShift = (theRow-1)*myNbColumns, aLength = theData.size();
   for(i = 1; i <= aLength; i++) {
-    myTable[aShift + i] = theData[i-1];
+    myTable[(int)(aShift + i)] = theData[i-1]; //!< TODO: conversion from size_t to int
   }
 
   if(theRow > myNbRows) myNbRows = theRow;
@@ -134,9 +132,9 @@ void SALOMEDSImpl_AttributeTableOfReal::SetRowData(const int theRow,
   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
 }
 
-vector<double> SALOMEDSImpl_AttributeTableOfReal::GetRowData(const int theRow)
+std::vector<double> SALOMEDSImpl_AttributeTableOfReal::GetRowData(const int theRow)
 {
-  vector<double> aSeq;
+  std::vector<double> aSeq;
   int i, aShift = (theRow-1)*myNbColumns;
   for(i = 1; i <= myNbColumns; i++) {
      if(myTable.find(aShift+i) != myTable.end()) 
@@ -148,9 +146,8 @@ vector<double> SALOMEDSImpl_AttributeTableOfReal::GetRowData(const int theRow)
   return aSeq;
 }
 
-
 void SALOMEDSImpl_AttributeTableOfReal::SetRowTitle(const int theRow,
-                                                   const std::string& theTitle) 
+                                                    const std::string& theTitle) 
 {
   CheckLocked();  
   Backup();
@@ -165,7 +162,7 @@ void SALOMEDSImpl_AttributeTableOfReal::SetRowTitle(const int theRow,
 }
 
 void SALOMEDSImpl_AttributeTableOfReal::SetRowUnit(const int theRow,
-                                                  const std::string& theUnit) 
+                                                   const std::string& theUnit) 
 {
   CheckLocked();  
   Backup();
@@ -178,41 +175,40 @@ void SALOMEDSImpl_AttributeTableOfReal::SetRowUnit(const int theRow,
   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
 }
 
-void SALOMEDSImpl_AttributeTableOfReal::SetRowUnits(const vector<string>& theUnits)
+void SALOMEDSImpl_AttributeTableOfReal::SetRowUnits(const std::vector<std::string>& theUnits)
 {
-  if (theUnits.size() != GetNbRows()) throw DFexception("Invalid number of rows");
-  int aLength = theUnits.size(), i;
-  for(i = 1; i <= aLength; i++) SetRowUnit(i, theUnits[i-1]);
+  if ((int)theUnits.size() != GetNbRows()) throw DFexception("Invalid number of rows");
+  size_t aLength = theUnits.size(), i;
+  for(i = 1; i <= aLength; i++) SetRowUnit((int)i, theUnits[i-1]); //!< TODO: conversion from size_t to int
   
   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
 }
 
-vector<string> SALOMEDSImpl_AttributeTableOfReal::GetRowUnits()
+std::vector<std::string> SALOMEDSImpl_AttributeTableOfReal::GetRowUnits()
 {
-  vector<string> aSeq;
-  int aLength = myRows.size(), i;
+  std::vector<std::string> aSeq;
+  size_t aLength = myRows.size(), i;
   for(i=0; i<aLength; i++) aSeq.push_back(getUnit(myRows[i]));
   return aSeq;
 }
 
-void SALOMEDSImpl_AttributeTableOfReal::SetRowTitles(const vector<string>& theTitles)
+void SALOMEDSImpl_AttributeTableOfReal::SetRowTitles(const std::vector<std::string>& theTitles)
 {
-  if (theTitles.size() != GetNbRows()) throw DFexception("Invalid number of rows");
-  int aLength = theTitles.size(), i;
-  for(i = 1; i <= aLength; i++) SetRowTitle(i, theTitles[i-1]);
+  if ((int)theTitles.size() != GetNbRows()) throw DFexception("Invalid number of rows");
+  size_t aLength = theTitles.size(), i;
+  for(i = 1; i <= aLength; i++) SetRowTitle((int)i, theTitles[i-1]); //!< TODO: conversion from size_t to int
   
   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
 }
 
-vector<string> SALOMEDSImpl_AttributeTableOfReal::GetRowTitles()
+std::vector<std::string> SALOMEDSImpl_AttributeTableOfReal::GetRowTitles()
 {
-  vector<string> aSeq;
-  int aLength = myRows.size(), i;
+  std::vector<std::string> aSeq;
+  size_t aLength = myRows.size(), i;
   for(i=0; i<aLength; i++) aSeq.push_back(getTitle(myRows[i]));
   return aSeq;
 }
 
-
 std::string SALOMEDSImpl_AttributeTableOfReal::GetRowTitle(const int theRow) const 
 {
   return getTitle(myRows[theRow-1]);
@@ -225,32 +221,31 @@ std::string SALOMEDSImpl_AttributeTableOfReal::GetRowUnit(const int theRow) cons
 }
 
 void SALOMEDSImpl_AttributeTableOfReal::SetColumnData(const int theColumn,
-                                                     const vector<double>& theData) 
+                                                      const std::vector<double>& theData) 
 {
   CheckLocked();  
   if(theColumn > myNbColumns) SetNbColumns(theColumn);
 
   Backup();
 
-  int i, aLength = theData.size();
+  size_t i, aLength = theData.size();
   for(i = 1; i <= aLength; i++) {
-    myTable[myNbColumns*(i-1)+theColumn] = theData[i-1];
+    myTable[myNbColumns*((int)i-1)+theColumn] = theData[i-1]; //!< TODO: conversion from size_t to int
   }
 
-  if(aLength > myNbRows) {
-    myNbRows = aLength;
-    while (myRows.size() < myNbRows) { // append empty row titles
-      myRows.push_back(string(""));
+  if((int)aLength > myNbRows) {
+    myNbRows = (int)aLength; //!< TODO: conversion from size_t to int
+    while ((int)myRows.size() < myNbRows) { // append empty row titles
+      myRows.push_back(std::string(""));
     }
   }
   
   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
 }
 
-
-vector<double> SALOMEDSImpl_AttributeTableOfReal::GetColumnData(const int theColumn)
+std::vector<double> SALOMEDSImpl_AttributeTableOfReal::GetColumnData(const int theColumn)
 {
-  vector<double> aSeq;
+  std::vector<double> aSeq;
   
   int i, anIndex;
   for(i = 1; i <= myNbRows; i++) {
@@ -265,11 +260,11 @@ vector<double> SALOMEDSImpl_AttributeTableOfReal::GetColumnData(const int theCol
 }
 
 void SALOMEDSImpl_AttributeTableOfReal::SetColumnTitle(const int theColumn,
-                                                      const std::string& theTitle) 
+                                                       const std::string& theTitle) 
 {
   CheckLocked();  
   Backup();
-  while(myCols.size() < theColumn) myCols.push_back(std::string(""));
+  while((int)myCols.size() < theColumn) myCols.push_back(std::string(""));
   myCols[theColumn-1] = theTitle;
 
   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
@@ -278,23 +273,23 @@ void SALOMEDSImpl_AttributeTableOfReal::SetColumnTitle(const int theColumn,
 std::string SALOMEDSImpl_AttributeTableOfReal::GetColumnTitle(const int theColumn) const 
 {
   if(myCols.empty()) return "";
-  if(myCols.size() < theColumn) return "";
+  if((int)myCols.size() < theColumn) return "";
   return myCols[theColumn-1];
 }
 
-void SALOMEDSImpl_AttributeTableOfReal::SetColumnTitles(const vector<string>& theTitles)
+void SALOMEDSImpl_AttributeTableOfReal::SetColumnTitles(const std::vector<std::string>& theTitles)
 {
-  if (theTitles.size() != myNbColumns) throw DFexception("Invalid number of columns");
-  int aLength = theTitles.size(), i;
+  if ((int)theTitles.size() != myNbColumns) throw DFexception("Invalid number of columns");
+  size_t aLength = theTitles.size(), i;
   for(i = 0; i < aLength; i++)  myCols[i] = theTitles[i];
   
   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
 }
 
-vector<string> SALOMEDSImpl_AttributeTableOfReal::GetColumnTitles()
+std::vector<std::string> SALOMEDSImpl_AttributeTableOfReal::GetColumnTitles()
 {
-  vector<string> aSeq;
-  int aLength = myCols.size(), i;
+  std::vector<std::string> aSeq;
+  size_t aLength = myCols.size(), i;
   for(i=0; i<aLength; i++) aSeq.push_back(myCols[i]);
   return aSeq;
 }
@@ -310,17 +305,18 @@ int SALOMEDSImpl_AttributeTableOfReal::GetNbColumns() const
 }
 
 void SALOMEDSImpl_AttributeTableOfReal::PutValue(const double& theValue,
-                                                const int theRow,
-                                                const int theColumn) 
+                                                 const int theRow,
+                                                 const int theColumn) 
 {
   CheckLocked();      
+  //Backup();
   if(theColumn > myNbColumns) SetNbColumns(theColumn);
 
   int anIndex = (theRow-1)*myNbColumns + theColumn;
   myTable[anIndex] =  theValue;
 
   if(theRow > myNbRows) {
-    while (myRows.size() < theRow) { // append empty row titles
+    while ((int)myRows.size() < theRow) { // append empty row titles
       myRows.push_back(std::string(""));
     }
     myNbRows = theRow;
@@ -330,7 +326,7 @@ void SALOMEDSImpl_AttributeTableOfReal::PutValue(const double& theValue,
 }
 
 bool SALOMEDSImpl_AttributeTableOfReal::HasValue(const int theRow,
-                                                const int theColumn) 
+                                                 const int theColumn) 
 {
   if(theRow > myNbRows || theRow < 1) return false;
   if(theColumn > myNbColumns || theColumn < 1) return false;
@@ -339,7 +335,7 @@ bool SALOMEDSImpl_AttributeTableOfReal::HasValue(const int theRow,
 }
 
 double SALOMEDSImpl_AttributeTableOfReal::GetValue(const int theRow,
-                                                  const int theColumn) 
+                                                   const int theColumn) 
 {
   if(theRow > myNbRows || theRow < 1) throw DFexception("Invalid cell index");
   if(theColumn > myNbColumns || theColumn < 1) throw DFexception("Invalid cell index");
@@ -351,6 +347,20 @@ double SALOMEDSImpl_AttributeTableOfReal::GetValue(const int theRow,
   return 0.;
 }
 
+void SALOMEDSImpl_AttributeTableOfReal::RemoveValue(const int theRow, const int theColumn)
+{
+  CheckLocked();  
+  if(theRow > myNbRows || theRow < 1) throw DFexception("Invalid cell index");
+  if(theColumn > myNbColumns || theColumn < 1) throw DFexception("Invalid cell index");
+
+  int anIndex = (theRow-1)*myNbColumns + theColumn;
+  if (myTable.find(anIndex) != myTable.end()) {
+    //Backup();
+    myTable.erase(anIndex);
+    SetModifyFlag(); // table is modified
+  }
+}
+
 const std::string& SALOMEDSImpl_AttributeTableOfReal::ID() const
 {
   return GetID();
@@ -404,10 +414,9 @@ void SALOMEDSImpl_AttributeTableOfReal::Paste(DF_Attribute* into)
     aTable->myCols.push_back(GetColumnTitle(anIndex));
 }
 
-
-vector<int> SALOMEDSImpl_AttributeTableOfReal::GetSetRowIndices(const int theRow)
+std::vector<int> SALOMEDSImpl_AttributeTableOfReal::GetSetRowIndices(const int theRow)
 {
-  vector<int> aSeq;
+  std::vector<int> aSeq;
 
   int i, aShift = myNbColumns*(theRow-1);
   for(i = 1; i <= myNbColumns; i++) {
@@ -417,9 +426,9 @@ vector<int> SALOMEDSImpl_AttributeTableOfReal::GetSetRowIndices(const int theRow
   return aSeq;
 }
 
-vector<int> SALOMEDSImpl_AttributeTableOfReal::GetSetColumnIndices(const int theColumn)
+std::vector<int> SALOMEDSImpl_AttributeTableOfReal::GetSetColumnIndices(const int theColumn)
 {
-  vector<int> aSeq;
+  std::vector<int> aSeq;
 
   int i, anIndex;
   for(i = 1; i <= myNbRows; i++) {
@@ -430,14 +439,14 @@ vector<int> SALOMEDSImpl_AttributeTableOfReal::GetSetColumnIndices(const int the
   return aSeq;
 }
 
-string SALOMEDSImpl_AttributeTableOfReal::Save() 
+std::string SALOMEDSImpl_AttributeTableOfReal::Save() 
 {
-  string aString;
+  std::string aString;
   char* buffer = new char[1024];
   int i, j, l;
 
   //Title
-  l = myTitle.size();
+  l = (int)myTitle.size();
   sprintf(buffer, "%d\n", l);
   aString+=buffer;
   for(i=0; i<l; i++) {
@@ -451,7 +460,7 @@ string SALOMEDSImpl_AttributeTableOfReal::Save()
 
   //Row titles
   for(i=0; i<myNbRows; i++) {
-    l = myRows[i].size();
+    l = (int)myRows[i].size();
     sprintf(buffer, "%d\n", l);
     aString+=buffer;
     for(j=0; j<l; j++) {
@@ -466,7 +475,7 @@ string SALOMEDSImpl_AttributeTableOfReal::Save()
 
   //Columns titles
   for(i=0; i<myNbColumns; i++) {
-    l = myCols[i].size();
+    l = (int)myCols[i].size();
     sprintf(buffer, "%d\n", l);
     aString+=buffer;
     for(j=0; j<l; j++) {
@@ -476,7 +485,7 @@ string SALOMEDSImpl_AttributeTableOfReal::Save()
   }
 
   //Store the table values
-  l = myTable.size();
+  l = (int)myTable.size();
   sprintf(buffer, "%d\n", l);
   aString+=buffer;
   for(MI p = myTable.begin(); p != myTable.end(); p++) {
@@ -488,9 +497,9 @@ string SALOMEDSImpl_AttributeTableOfReal::Save()
   return aString;
 }
 
-void SALOMEDSImpl_AttributeTableOfReal::Load(const string& value) 
+void SALOMEDSImpl_AttributeTableOfReal::Load(const std::string& value) 
 {
-  vector<string> v;
+  std::vector<std::string> v;
   int i,  j, l, pos, aSize = (int)value.size(); 
   for(i = 0, pos = 0; i<aSize; i++) {
     if(value[i] == '\n') {
@@ -550,3 +559,218 @@ void SALOMEDSImpl_AttributeTableOfReal::Load(const string& value)
   }
 
 }
+
+std::vector<int> SALOMEDSImpl_AttributeTableOfReal::SortRow(const int theRow, SortOrder sortOrder, SortPolicy sortPolicy )
+{
+  CheckLocked();  
+  std::vector<int> result;
+  if ( theRow > 0 && theRow <= myNbRows ) {
+    std::vector<int> indices( myNbColumns );
+    int cnt = 0;
+    for ( int i = 0; i < myNbColumns; i++ ) {
+      if ( sortPolicy != EmptyIgnore || HasValue(theRow, i+1) ) {
+       indices[cnt++] = i+1;
+      }
+    }
+    indices.resize(cnt);
+    
+    TableSorter<SALOMEDSImpl_AttributeTableOfReal> sorter( this, sortOrder, sortPolicy, theRow, true );
+    std::stable_sort( indices.begin(), indices.end(), sorter );
+
+    if ( sortPolicy == EmptyIgnore ) {
+      std::vector<int> other( myNbColumns );
+      cnt = 0;
+      for( int i = 0; i < myNbColumns; i++ )
+       other[i] = HasValue(theRow, i+1) ? indices[cnt++] : i+1;
+      indices = other;
+    }
+    result = indices;
+
+    for ( int col = 0; col < (int)indices.size(); col++ ) {
+      int idx = indices[col];
+      if ( col+1 == idx ) continue;
+      SwapCells(theRow, col+1, theRow, idx);
+      int idx1 = 0;
+      for ( int i = col+1; i < (int)indices.size() && idx1 == 0; i++)
+       if ( indices[i] == col+1 ) idx1 = i;
+      indices[idx1] = idx;
+    }
+    // no need for SetModifyFlag(), since it is done by SwapCells()
+  }
+  return result;
+}
+
+std::vector<int> SALOMEDSImpl_AttributeTableOfReal::SortColumn(const int theColumn, SortOrder sortOrder, SortPolicy sortPolicy )
+{
+  CheckLocked();  
+  std::vector<int> result;
+  if ( theColumn > 0 && theColumn <= myNbColumns ) {
+    std::vector<int> indices( myNbRows );
+    int cnt = 0;
+    for ( int i = 0; i < myNbRows; i++ ) {
+      if ( sortPolicy != EmptyIgnore || HasValue(i+1, theColumn) ) {
+       indices[cnt++] = i+1;
+      }
+    }
+    indices.resize(cnt);
+    
+    TableSorter<SALOMEDSImpl_AttributeTableOfReal> sorter( this, sortOrder, sortPolicy, theColumn, false );
+    std::stable_sort( indices.begin(), indices.end(), sorter );
+
+    if ( sortPolicy == EmptyIgnore ) {
+      std::vector<int> other( myNbRows );
+      cnt = 0;
+      for( int i = 0; i < myNbRows; i++ )
+       other[i] = HasValue(i+1, theColumn) ? indices[cnt++] : i+1;
+      indices = other;
+    }
+    result = indices;
+
+    for ( int row = 0; row < (int)indices.size(); row++ ) {
+      int idx = indices[row];
+      if ( row+1 == idx ) continue;
+      SwapCells(row+1, theColumn, idx, theColumn);
+      int idx1 = 0;
+      for ( int i = row+1; i < (int)indices.size() && idx1 == 0; i++)
+       if ( indices[i] == row+1 ) idx1 = i;
+      indices[idx1] = idx;
+    }
+    // no need for SetModifyFlag(), since it is done by SwapCells()
+  }
+  return result;
+}
+
+std::vector<int> SALOMEDSImpl_AttributeTableOfReal::SortByRow(const int theRow, SortOrder sortOrder, SortPolicy sortPolicy )
+{
+  CheckLocked();  
+  std::vector<int> result;
+  if ( theRow > 0 && theRow <= myNbRows ) {
+    std::vector<int> indices( myNbColumns );
+    int cnt = 0;
+    for ( int i = 0; i < myNbColumns; i++ ) {
+      if ( sortPolicy != EmptyIgnore || HasValue(theRow, i+1) ) {
+       indices[cnt++] = i+1;
+      }
+    }
+    indices.resize(cnt);
+    
+    TableSorter<SALOMEDSImpl_AttributeTableOfReal> sorter( this, sortOrder, sortPolicy, theRow, true );
+    std::stable_sort( indices.begin(), indices.end(), sorter );
+
+    if ( sortPolicy == EmptyIgnore ) {
+      std::vector<int> other( myNbColumns );
+      cnt = 0;
+      for( int i = 0; i < myNbColumns; i++ )
+       other[i] = HasValue(theRow, i+1) ? indices[cnt++] : i+1;
+      indices = other;
+    }
+    result = indices;
+
+    for ( int col = 0; col < (int)indices.size(); col++ ) {
+      int idx = indices[col];
+      if ( col+1 == idx ) continue;
+      SwapColumns(col+1, idx);
+      int idx1 = 0;
+      for ( int i = col+1; i < (int)indices.size() && idx1 == 0; i++)
+       if ( indices[i] == col+1 ) idx1 = i;
+      indices[idx1] = idx;
+    }
+    // no need for SetModifyFlag(), since it is done by SwapColumns()
+  }
+  return result;
+}
+
+std::vector<int> SALOMEDSImpl_AttributeTableOfReal::SortByColumn(const int theColumn, SortOrder sortOrder, SortPolicy sortPolicy )
+{
+  CheckLocked();  
+  std::vector<int> result;
+  if ( theColumn > 0 && theColumn <= myNbColumns ) {
+    std::vector<int> indices( myNbRows );
+    int cnt = 0;
+    for ( int i = 0; i < myNbRows; i++ ) {
+      if ( sortPolicy != EmptyIgnore || HasValue(i+1, theColumn) ) {
+       indices[cnt++] = i+1;
+      }
+    }
+    indices.resize(cnt);
+    
+    TableSorter<SALOMEDSImpl_AttributeTableOfReal> sorter( this, sortOrder, sortPolicy, theColumn, false );
+    std::stable_sort( indices.begin(), indices.end(), sorter );
+
+    if ( sortPolicy == EmptyIgnore ) {
+      std::vector<int> other( myNbRows );
+      cnt = 0;
+      for( int i = 0; i < myNbRows; i++ )
+       other[i] = HasValue(i+1, theColumn) ? indices[cnt++] : i+1;
+      indices = other;
+    }
+    result = indices;
+
+    for ( int row = 0; row < (int)indices.size(); row++ ) {
+      int idx = indices[row];
+      if ( row+1 == idx ) continue;
+      SwapRows(row+1, idx);
+      int idx1 = 0;
+      for ( int i = row+1; i < (int)indices.size() && idx1 == 0; i++)
+       if ( indices[i] == row+1 ) idx1 = i;
+      indices[idx1] = idx;
+    }
+    // no need for SetModifyFlag(), since it is done by SwapRows()
+  }
+  return result;
+}
+
+void SALOMEDSImpl_AttributeTableOfReal::SwapCells(const int theRow1, const int theColumn1, 
+                                                 const int theRow2, const int theColumn2)
+{
+  CheckLocked();  
+  if (theRow1    > myNbRows    || theRow1 < 1)    throw DFexception("Invalid cell index");
+  if (theRow2    > myNbRows    || theRow2 < 1)    throw DFexception("Invalid cell index");
+  if (theColumn1 > myNbColumns || theColumn1 < 1) throw DFexception("Invalid cell index");
+  if (theColumn2 > myNbColumns || theColumn2 < 1) throw DFexception("Invalid cell index");
+
+  int anIndex1 = (theRow1-1)*myNbColumns + theColumn1;
+  int anIndex2 = (theRow2-1)*myNbColumns + theColumn2;
+
+  bool hasValue1 = myTable.find(anIndex1) != myTable.end();
+  bool hasValue2 = myTable.find(anIndex2) != myTable.end();
+
+  if (!hasValue1 && !hasValue2) return;                   // nothing changed
+
+  double value1  = hasValue1 ? myTable[anIndex1] : 0;
+  double value2  = hasValue2 ? myTable[anIndex2] : 0;
+
+  if (hasValue1 && hasValue2 && value1 == value2) return; // nothing changed
+
+  if (hasValue1) myTable[anIndex2] = value1;
+  else           myTable.erase(anIndex2);
+  if (hasValue2) myTable[anIndex1] = value2;
+  else           myTable.erase(anIndex1);
+
+  SetModifyFlag(); // table is modified
+}
+
+void SALOMEDSImpl_AttributeTableOfReal::SwapRows(const int theRow1, const int theRow2)
+{
+  CheckLocked();  
+  for (int i = 1; i <= myNbColumns; i++)
+    SwapCells(theRow1, i, theRow2, i);
+  // swap row titles
+  std::string tmp = myRows[theRow1-1];
+  myRows[theRow1-1] = myRows[theRow2-1];
+  myRows[theRow2-1] = tmp;
+  // no need for SetModifyFlag(), since it is done by SwapCells()
+}
+
+void SALOMEDSImpl_AttributeTableOfReal::SwapColumns(const int theColumn1, const int theColumn2)
+{
+  CheckLocked();  
+  for (int i = 1; i <= myNbRows; i++)
+    SwapCells(i, theColumn1, i, theColumn2);
+  // swap column titles
+  std::string tmp = myCols[theColumn1-1];
+  myCols[theColumn1-1] = myCols[theColumn2-1];
+  myCols[theColumn2-1] = tmp;
+  // no need for SetModifyFlag(), since it is done by SwapCells()
+}
+