Back to index

salome-kernel  6.5.0
SALOMEDSImpl_AttributeTableOfReal.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 //  File   : SALOMEDSImpl_AttributeTableOfReal.cxx
00024 //  Author : Michael Ponikarov
00025 //  Module : SALOME
00026 //
00027 #include "SALOMEDSImpl_AttributeTableOfReal.hxx"
00028 
00029 #include <sstream>
00030 #include <algorithm>
00031 
00032 #define SEPARATOR '\1'
00033 typedef std::map<int, double>::const_iterator MI;
00034 
00035 static std::string getUnit(const std::string& theString)
00036 {
00037   std::string aString(theString);
00038   int aPos = aString.find(SEPARATOR);
00039   return aPos < 0 || aPos == aString.size()-1 ? std::string() : aString.substr(aPos+1, aString.size());
00040 }
00041 
00042 static std::string getTitle(const std::string& theString)
00043 {
00044   std::string aString(theString);
00045   int aPos = aString.find(SEPARATOR);
00046   return aPos < 0 ? aString :aString.substr(0, aPos);
00047 }
00048 
00049 const std::string& SALOMEDSImpl_AttributeTableOfReal::GetID() 
00050 {
00051   static std::string SALOMEDSImpl_AttributeTableOfRealID ("128371A1-8F52-11d6-A8A3-0001021E8C7F");
00052   return SALOMEDSImpl_AttributeTableOfRealID;
00053 }
00054 
00055 SALOMEDSImpl_AttributeTableOfReal* SALOMEDSImpl_AttributeTableOfReal::Set(const DF_Label& label) 
00056 {
00057   SALOMEDSImpl_AttributeTableOfReal* A = NULL;
00058   if (!(A=(SALOMEDSImpl_AttributeTableOfReal*)label.FindAttribute(SALOMEDSImpl_AttributeTableOfReal::GetID()))) {
00059     A = new SALOMEDSImpl_AttributeTableOfReal();
00060     label.AddAttribute(A);
00061   }
00062   return A;
00063 }
00064 
00065 SALOMEDSImpl_AttributeTableOfReal::SALOMEDSImpl_AttributeTableOfReal() 
00066 :SALOMEDSImpl_GenericAttribute("AttributeTableOfReal")
00067 {
00068   myNbRows = 0;
00069   myNbColumns = 0;
00070 }
00071 
00072 void SALOMEDSImpl_AttributeTableOfReal::SetNbColumns(const int theNbColumns)
00073 {
00074   CheckLocked();  
00075   Backup();
00076   
00077   std::map<int, double> aMap;
00078   aMap = myTable;
00079   myTable.clear();
00080 
00081   for(MI p = aMap.begin(); p != aMap.end(); p++) {
00082     int aRow = (int)(p->first/myNbColumns) + 1;
00083     int aCol = (int)(p->first - myNbColumns*(aRow-1));
00084     if(aCol == 0) { aCol = myNbColumns; aRow--; }
00085     if(aCol > theNbColumns) continue;
00086     int aKey = (aRow-1)*theNbColumns+aCol;
00087     myTable[aKey] = p->second;
00088   }
00089 
00090   myNbColumns = theNbColumns;
00091 
00092   while (myCols.size() < myNbColumns) { // append empty columns titles
00093     myCols.push_back(std::string(""));
00094   }
00095   
00096   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
00097 }
00098 
00099 void SALOMEDSImpl_AttributeTableOfReal::SetTitle(const std::string& theTitle) 
00100 {
00101   CheckLocked();  
00102   Backup();
00103   myTitle = theTitle;
00104   
00105   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
00106 }
00107 
00108 std::string SALOMEDSImpl_AttributeTableOfReal::GetTitle() const 
00109 {
00110   return myTitle;
00111 }
00112 
00113 void SALOMEDSImpl_AttributeTableOfReal::SetRowData(const int theRow,
00114                                                    const std::vector<double>& theData) 
00115 {
00116   CheckLocked();  
00117   if(theData.size() > myNbColumns) SetNbColumns(theData.size());
00118 
00119   Backup();
00120 
00121   while (myRows.size() < theRow) { // append new row titles
00122     myRows.push_back(std::string(""));
00123   }
00124 
00125   int i, aShift = (theRow-1)*myNbColumns, aLength = theData.size();
00126   for(i = 1; i <= aLength; i++) {
00127     myTable[aShift + i] = theData[i-1];
00128   }
00129 
00130   if(theRow > myNbRows) myNbRows = theRow;
00131   
00132   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
00133 }
00134 
00135 std::vector<double> SALOMEDSImpl_AttributeTableOfReal::GetRowData(const int theRow)
00136 {
00137   std::vector<double> aSeq;
00138   int i, aShift = (theRow-1)*myNbColumns;
00139   for(i = 1; i <= myNbColumns; i++) {
00140      if(myTable.find(aShift+i) != myTable.end()) 
00141        aSeq.push_back(myTable[aShift+i]);
00142      else
00143        aSeq.push_back(0.);
00144   }
00145   
00146   return aSeq;
00147 }
00148 
00149 void SALOMEDSImpl_AttributeTableOfReal::SetRowTitle(const int theRow,
00150                                                     const std::string& theTitle) 
00151 {
00152   CheckLocked();  
00153   Backup();
00154   std::string aTitle(theTitle), aUnit = GetRowUnit(theRow);
00155   if(aUnit.size()>0) {
00156     aTitle += SEPARATOR;
00157     aTitle += aUnit;
00158   }
00159   myRows[theRow-1] = aTitle;
00160   
00161   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
00162 }
00163 
00164 void SALOMEDSImpl_AttributeTableOfReal::SetRowUnit(const int theRow,
00165                                                    const std::string& theUnit) 
00166 {
00167   CheckLocked();  
00168   Backup();
00169   std::string aTitle = GetRowTitle(theRow);
00170   aTitle += SEPARATOR;
00171   aTitle += theUnit;
00172   
00173   myRows[theRow-1] = aTitle;
00174   
00175   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
00176 }
00177 
00178 void SALOMEDSImpl_AttributeTableOfReal::SetRowUnits(const std::vector<std::string>& theUnits)
00179 {
00180   if (theUnits.size() != GetNbRows()) throw DFexception("Invalid number of rows");
00181   int aLength = theUnits.size(), i;
00182   for(i = 1; i <= aLength; i++) SetRowUnit(i, theUnits[i-1]);
00183   
00184   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
00185 }
00186 
00187 std::vector<std::string> SALOMEDSImpl_AttributeTableOfReal::GetRowUnits()
00188 {
00189   std::vector<std::string> aSeq;
00190   int aLength = myRows.size(), i;
00191   for(i=0; i<aLength; i++) aSeq.push_back(getUnit(myRows[i]));
00192   return aSeq;
00193 }
00194 
00195 void SALOMEDSImpl_AttributeTableOfReal::SetRowTitles(const std::vector<std::string>& theTitles)
00196 {
00197   if (theTitles.size() != GetNbRows()) throw DFexception("Invalid number of rows");
00198   int aLength = theTitles.size(), i;
00199   for(i = 1; i <= aLength; i++) SetRowTitle(i, theTitles[i-1]);
00200   
00201   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
00202 }
00203 
00204 std::vector<std::string> SALOMEDSImpl_AttributeTableOfReal::GetRowTitles()
00205 {
00206   std::vector<std::string> aSeq;
00207   int aLength = myRows.size(), i;
00208   for(i=0; i<aLength; i++) aSeq.push_back(getTitle(myRows[i]));
00209   return aSeq;
00210 }
00211 
00212 std::string SALOMEDSImpl_AttributeTableOfReal::GetRowTitle(const int theRow) const 
00213 {
00214   return getTitle(myRows[theRow-1]);
00215 }
00216 
00217 
00218 std::string SALOMEDSImpl_AttributeTableOfReal::GetRowUnit(const int theRow) const 
00219 {
00220   return getUnit(myRows[theRow-1]);
00221 }
00222 
00223 void SALOMEDSImpl_AttributeTableOfReal::SetColumnData(const int theColumn,
00224                                                       const std::vector<double>& theData) 
00225 {
00226   CheckLocked();  
00227   if(theColumn > myNbColumns) SetNbColumns(theColumn);
00228 
00229   Backup();
00230 
00231   int i, aLength = theData.size();
00232   for(i = 1; i <= aLength; i++) {
00233     myTable[myNbColumns*(i-1)+theColumn] = theData[i-1];
00234   }
00235 
00236   if(aLength > myNbRows) {
00237     myNbRows = aLength;
00238     while (myRows.size() < myNbRows) { // append empty row titles
00239       myRows.push_back(std::string(""));
00240     }
00241   }
00242   
00243   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
00244 }
00245 
00246 std::vector<double> SALOMEDSImpl_AttributeTableOfReal::GetColumnData(const int theColumn)
00247 {
00248   std::vector<double> aSeq;
00249   
00250   int i, anIndex;
00251   for(i = 1; i <= myNbRows; i++) {
00252     anIndex = myNbColumns*(i-1) + theColumn;
00253     if(myTable.find(anIndex) != myTable.end()) 
00254       aSeq.push_back(myTable[anIndex]);
00255     else
00256       aSeq.push_back(0.);
00257   }
00258   
00259   return aSeq;
00260 }
00261 
00262 void SALOMEDSImpl_AttributeTableOfReal::SetColumnTitle(const int theColumn,
00263                                                        const std::string& theTitle) 
00264 {
00265   CheckLocked();  
00266   Backup();
00267   while(myCols.size() < theColumn) myCols.push_back(std::string(""));
00268   myCols[theColumn-1] = theTitle;
00269 
00270   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
00271 }
00272 
00273 std::string SALOMEDSImpl_AttributeTableOfReal::GetColumnTitle(const int theColumn) const 
00274 {
00275   if(myCols.empty()) return "";
00276   if(myCols.size() < theColumn) return "";
00277   return myCols[theColumn-1];
00278 }
00279 
00280 void SALOMEDSImpl_AttributeTableOfReal::SetColumnTitles(const std::vector<std::string>& theTitles)
00281 {
00282   if (theTitles.size() != myNbColumns) throw DFexception("Invalid number of columns");
00283   int aLength = theTitles.size(), i;
00284   for(i = 0; i < aLength; i++)  myCols[i] = theTitles[i];
00285   
00286   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
00287 }
00288 
00289 std::vector<std::string> SALOMEDSImpl_AttributeTableOfReal::GetColumnTitles()
00290 {
00291   std::vector<std::string> aSeq;
00292   int aLength = myCols.size(), i;
00293   for(i=0; i<aLength; i++) aSeq.push_back(myCols[i]);
00294   return aSeq;
00295 }
00296 
00297 int SALOMEDSImpl_AttributeTableOfReal::GetNbRows() const
00298 {
00299   return myNbRows;
00300 }
00301 
00302 int SALOMEDSImpl_AttributeTableOfReal::GetNbColumns() const
00303 {
00304   return myNbColumns;
00305 }
00306 
00307 void SALOMEDSImpl_AttributeTableOfReal::PutValue(const double& theValue,
00308                                                  const int theRow,
00309                                                  const int theColumn) 
00310 {
00311   CheckLocked();      
00312   //Backup();
00313   if(theColumn > myNbColumns) SetNbColumns(theColumn);
00314 
00315   int anIndex = (theRow-1)*myNbColumns + theColumn;
00316   myTable[anIndex] =  theValue;
00317 
00318   if(theRow > myNbRows) {
00319     while (myRows.size() < theRow) { // append empty row titles
00320       myRows.push_back(std::string(""));
00321     }
00322     myNbRows = theRow;
00323   }
00324   
00325   SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved 
00326 }
00327 
00328 bool SALOMEDSImpl_AttributeTableOfReal::HasValue(const int theRow,
00329                                                  const int theColumn) 
00330 {
00331   if(theRow > myNbRows || theRow < 1) return false;
00332   if(theColumn > myNbColumns || theColumn < 1) return false;
00333   int anIndex = (theRow-1)*myNbColumns + theColumn;
00334   return (myTable.find(anIndex) != myTable.end()); 
00335 }
00336 
00337 double SALOMEDSImpl_AttributeTableOfReal::GetValue(const int theRow,
00338                                                    const int theColumn) 
00339 {
00340   if(theRow > myNbRows || theRow < 1) throw DFexception("Invalid cell index");
00341   if(theColumn > myNbColumns || theColumn < 1) throw DFexception("Invalid cell index");
00342 
00343   int anIndex = (theRow-1)*myNbColumns + theColumn;
00344   if(myTable.find(anIndex) != myTable.end()) return myTable[anIndex];
00345   
00346   throw DFexception("Invalid cell index");
00347   return 0.;
00348 }
00349 
00350 void SALOMEDSImpl_AttributeTableOfReal::RemoveValue(const int theRow, const int theColumn)
00351 {
00352   CheckLocked();  
00353   if(theRow > myNbRows || theRow < 1) throw DFexception("Invalid cell index");
00354   if(theColumn > myNbColumns || theColumn < 1) throw DFexception("Invalid cell index");
00355 
00356   int anIndex = (theRow-1)*myNbColumns + theColumn;
00357   if (myTable.find(anIndex) != myTable.end()) {
00358     //Backup();
00359     myTable.erase(anIndex);
00360     SetModifyFlag(); // table is modified
00361   }
00362 }
00363 
00364 const std::string& SALOMEDSImpl_AttributeTableOfReal::ID() const
00365 {
00366   return GetID();
00367 }
00368 
00369 void SALOMEDSImpl_AttributeTableOfReal::Restore(DF_Attribute* with) 
00370 {
00371   int anIndex;
00372   SALOMEDSImpl_AttributeTableOfReal* aTable = dynamic_cast<SALOMEDSImpl_AttributeTableOfReal*>(with);
00373   if(!aTable) throw DFexception("Can't Restore from a null attribute");
00374 
00375   myTable.clear();
00376   myCols.clear();
00377   myRows.clear();
00378 
00379   myTable = aTable->myTable;
00380   myNbRows = aTable->myNbRows;
00381   myNbColumns = aTable->myNbColumns;
00382   myTitle = aTable->myTitle;
00383   
00384   for(anIndex = 1; anIndex <= aTable->GetNbRows();anIndex++)
00385     myRows.push_back(aTable->GetRowTitle(anIndex));
00386 
00387   for(anIndex = 1; anIndex <= aTable->GetNbColumns(); anIndex++) 
00388     myCols.push_back(aTable->GetColumnTitle(anIndex));
00389 }
00390 
00391 DF_Attribute* SALOMEDSImpl_AttributeTableOfReal::NewEmpty() const
00392 {
00393   return new SALOMEDSImpl_AttributeTableOfReal();
00394 }
00395 
00396 void SALOMEDSImpl_AttributeTableOfReal::Paste(DF_Attribute* into)
00397 {
00398   int anIndex;
00399   SALOMEDSImpl_AttributeTableOfReal* aTable = dynamic_cast<SALOMEDSImpl_AttributeTableOfReal*>(into);
00400   if(!aTable) throw DFexception("Can't Paste into a null attribute"); 
00401 
00402   aTable->myTable.clear();
00403   aTable->myCols.clear();
00404   aTable->myRows.clear();
00405 
00406   aTable->myTable = myTable;
00407   aTable->myTitle = myTitle;
00408   aTable->myNbRows = myNbRows;
00409   aTable->myNbColumns = myNbColumns;
00410 
00411   for(anIndex = 1; anIndex <= GetNbRows();anIndex++)
00412     aTable->myRows.push_back(GetRowTitle(anIndex));
00413   for(anIndex = 1; anIndex <= GetNbColumns(); anIndex++) 
00414     aTable->myCols.push_back(GetColumnTitle(anIndex));
00415 }
00416 
00417 std::vector<int> SALOMEDSImpl_AttributeTableOfReal::GetSetRowIndices(const int theRow)
00418 {
00419   std::vector<int> aSeq;
00420 
00421   int i, aShift = myNbColumns*(theRow-1);
00422   for(i = 1; i <= myNbColumns; i++) {
00423     if(myTable.find(aShift + i) != myTable.end()) aSeq.push_back(i);
00424   }
00425   
00426   return aSeq;
00427 }
00428 
00429 std::vector<int> SALOMEDSImpl_AttributeTableOfReal::GetSetColumnIndices(const int theColumn)
00430 {
00431   std::vector<int> aSeq;
00432 
00433   int i, anIndex;
00434   for(i = 1; i <= myNbRows; i++) {
00435     anIndex = myNbColumns*(i-1)+theColumn;
00436     if(myTable.find(anIndex) != myTable.end()) aSeq.push_back(i);
00437   }
00438   
00439   return aSeq;
00440 }
00441 
00442 std::string SALOMEDSImpl_AttributeTableOfReal::Save() 
00443 {
00444   std::string aString;
00445   char* buffer = new char[1024];
00446   int i, j, l;
00447 
00448   //Title
00449   l = myTitle.size();
00450   sprintf(buffer, "%d\n", l);
00451   aString+=buffer;
00452   for(i=0; i<l; i++) {
00453     aString += myTitle[i];
00454     aString +='\n';
00455   }
00456   
00457   //Nb rows
00458   sprintf(buffer, "%d\n", myNbRows);
00459   aString+=buffer;
00460 
00461   //Row titles
00462   for(i=0; i<myNbRows; i++) {
00463     l = myRows[i].size();
00464     sprintf(buffer, "%d\n", l);
00465     aString+=buffer;
00466     for(j=0; j<l; j++) {
00467       aString += myRows[i][j];
00468       aString += '\n';
00469     }
00470   }  
00471 
00472   //Nb columns
00473   sprintf(buffer, "%d\n", myNbColumns);
00474   aString+=buffer;
00475 
00476   //Columns titles
00477   for(i=0; i<myNbColumns; i++) {
00478     l = myCols[i].size();
00479     sprintf(buffer, "%d\n", l);
00480     aString+=buffer;
00481     for(j=0; j<l; j++) {
00482       aString += myCols[i][j];
00483       aString += '\n';
00484     }
00485   }
00486 
00487   //Store the table values
00488   l = myTable.size();
00489   sprintf(buffer, "%d\n", l);
00490   aString+=buffer;
00491   for(MI p = myTable.begin(); p != myTable.end(); p++) {
00492     sprintf(buffer, "%d\n%.64e\n", p->first, p->second);
00493     aString += buffer;
00494   }
00495 
00496   delete []buffer;
00497   return aString;
00498 }
00499 
00500 void SALOMEDSImpl_AttributeTableOfReal::Load(const std::string& value) 
00501 {
00502   std::vector<std::string> v;
00503   int i,  j, l, pos, aSize = (int)value.size(); 
00504   for(i = 0, pos = 0; i<aSize; i++) {
00505     if(value[i] == '\n') {
00506        v.push_back(value.substr(pos, i-pos));
00507        pos = i+1;
00508     }
00509   }
00510 
00511   Backup();
00512 
00513   pos = 0;
00514   std::string aStr;
00515 
00516   //Title
00517   l = strtol(v[pos++].c_str(), NULL, 10);
00518 
00519   myTitle = std::string(l, 0);
00520   for(i=0; i<l; i++) {
00521     myTitle[i] = v[pos++][0];
00522   }
00523 
00524   //Nb rows
00525   myNbRows = strtol(v[pos++].c_str(), NULL, 10);
00526 
00527   //Rows titles
00528   myRows.clear();  
00529   for(i=1; i<=myNbRows; i++) { 
00530     l = strtol(v[pos++].c_str(), NULL, 10);
00531     aStr = std::string(l,0);
00532     for(j=0; j<l; j++) {
00533       aStr[j] = v[pos++][0];
00534     }
00535     myRows.push_back(aStr);
00536   }
00537 
00538   //Nb columns
00539   myNbColumns = strtol(v[pos++].c_str(), NULL, 10);
00540 
00541   //Columns titles
00542   myCols.clear();
00543   for(i=1; i<=myNbColumns; i++) {
00544     l = strtol(v[pos++].c_str(), NULL, 10);
00545     aStr = std::string(l,0);
00546     for(j=0; j<l; j++) {
00547       aStr[j] = v[pos++][0];
00548     }
00549     myCols.push_back(aStr);
00550   }
00551 
00552   //Restore the table values
00553   l = strtol(v[pos++].c_str(), NULL, 10);
00554   myTable.clear();
00555   for(i=1; i<=l; i++) {
00556     int aKey = strtol(v[pos++].c_str(), NULL, 10);
00557     double aValue = strtod(v[pos++].c_str(), NULL);
00558     myTable[aKey] = aValue;
00559   }
00560 
00561 }
00562 
00563 std::vector<int> SALOMEDSImpl_AttributeTableOfReal::SortRow(const int theRow, SortOrder sortOrder, SortPolicy sortPolicy )
00564 {
00565   CheckLocked();  
00566   std::vector<int> result;
00567   if ( theRow > 0 && theRow <= myNbRows ) {
00568     std::vector<int> indices( myNbColumns );
00569     int cnt = 0;
00570     for ( int i = 0; i < myNbColumns; i++ ) {
00571       if ( sortPolicy != EmptyIgnore || HasValue(theRow, i+1) ) {
00572        indices[cnt++] = i+1;
00573       }
00574     }
00575     indices.resize(cnt);
00576     
00577     TableSorter<SALOMEDSImpl_AttributeTableOfReal> sorter( this, sortOrder, sortPolicy, theRow, true );
00578     std::stable_sort( indices.begin(), indices.end(), sorter );
00579 
00580     if ( sortPolicy == EmptyIgnore ) {
00581       std::vector<int> other( myNbColumns );
00582       cnt = 0;
00583       for( int i = 0; i < myNbColumns; i++ )
00584        other[i] = HasValue(theRow, i+1) ? indices[cnt++] : i+1;
00585       indices = other;
00586     }
00587     result = indices;
00588 
00589     for ( int col = 0; col < indices.size(); col++ ) {
00590       int idx = indices[col];
00591       if ( col+1 == idx ) continue;
00592       SwapCells(theRow, col+1, theRow, idx);
00593       int idx1 = 0;
00594       for ( int i = col+1; i < indices.size() && idx1 == 0; i++)
00595        if ( indices[i] == col+1 ) idx1 = i;
00596       indices[idx1] = idx;
00597     }
00598     // no need for SetModifyFlag(), since it is done by SwapCells()
00599   }
00600   return result;
00601 }
00602 
00603 std::vector<int> SALOMEDSImpl_AttributeTableOfReal::SortColumn(const int theColumn, SortOrder sortOrder, SortPolicy sortPolicy )
00604 {
00605   CheckLocked();  
00606   std::vector<int> result;
00607   if ( theColumn > 0 && theColumn <= myNbColumns ) {
00608     std::vector<int> indices( myNbRows );
00609     int cnt = 0;
00610     for ( int i = 0; i < myNbRows; i++ ) {
00611       if ( sortPolicy != EmptyIgnore || HasValue(i+1, theColumn) ) {
00612        indices[cnt++] = i+1;
00613       }
00614     }
00615     indices.resize(cnt);
00616     
00617     TableSorter<SALOMEDSImpl_AttributeTableOfReal> sorter( this, sortOrder, sortPolicy, theColumn, false );
00618     std::stable_sort( indices.begin(), indices.end(), sorter );
00619 
00620     if ( sortPolicy == EmptyIgnore ) {
00621       std::vector<int> other( myNbRows );
00622       cnt = 0;
00623       for( int i = 0; i < myNbRows; i++ )
00624        other[i] = HasValue(i+1, theColumn) ? indices[cnt++] : i+1;
00625       indices = other;
00626     }
00627     result = indices;
00628 
00629     for ( int row = 0; row < indices.size(); row++ ) {
00630       int idx = indices[row];
00631       if ( row+1 == idx ) continue;
00632       SwapCells(row+1, theColumn, idx, theColumn);
00633       int idx1 = 0;
00634       for ( int i = row+1; i < indices.size() && idx1 == 0; i++)
00635        if ( indices[i] == row+1 ) idx1 = i;
00636       indices[idx1] = idx;
00637     }
00638     // no need for SetModifyFlag(), since it is done by SwapCells()
00639   }
00640   return result;
00641 }
00642 
00643 std::vector<int> SALOMEDSImpl_AttributeTableOfReal::SortByRow(const int theRow, SortOrder sortOrder, SortPolicy sortPolicy )
00644 {
00645   CheckLocked();  
00646   std::vector<int> result;
00647   if ( theRow > 0 && theRow <= myNbRows ) {
00648     std::vector<int> indices( myNbColumns );
00649     int cnt = 0;
00650     for ( int i = 0; i < myNbColumns; i++ ) {
00651       if ( sortPolicy != EmptyIgnore || HasValue(theRow, i+1) ) {
00652        indices[cnt++] = i+1;
00653       }
00654     }
00655     indices.resize(cnt);
00656     
00657     TableSorter<SALOMEDSImpl_AttributeTableOfReal> sorter( this, sortOrder, sortPolicy, theRow, true );
00658     std::stable_sort( indices.begin(), indices.end(), sorter );
00659 
00660     if ( sortPolicy == EmptyIgnore ) {
00661       std::vector<int> other( myNbColumns );
00662       cnt = 0;
00663       for( int i = 0; i < myNbColumns; i++ )
00664        other[i] = HasValue(theRow, i+1) ? indices[cnt++] : i+1;
00665       indices = other;
00666     }
00667     result = indices;
00668 
00669     for ( int col = 0; col < indices.size(); col++ ) {
00670       int idx = indices[col];
00671       if ( col+1 == idx ) continue;
00672       SwapColumns(col+1, idx);
00673       int idx1 = 0;
00674       for ( int i = col+1; i < indices.size() && idx1 == 0; i++)
00675        if ( indices[i] == col+1 ) idx1 = i;
00676       indices[idx1] = idx;
00677     }
00678     // no need for SetModifyFlag(), since it is done by SwapColumns()
00679   }
00680   return result;
00681 }
00682 
00683 std::vector<int> SALOMEDSImpl_AttributeTableOfReal::SortByColumn(const int theColumn, SortOrder sortOrder, SortPolicy sortPolicy )
00684 {
00685   CheckLocked();  
00686   std::vector<int> result;
00687   if ( theColumn > 0 && theColumn <= myNbColumns ) {
00688     std::vector<int> indices( myNbRows );
00689     int cnt = 0;
00690     for ( int i = 0; i < myNbRows; i++ ) {
00691       if ( sortPolicy != EmptyIgnore || HasValue(i+1, theColumn) ) {
00692        indices[cnt++] = i+1;
00693       }
00694     }
00695     indices.resize(cnt);
00696     
00697     TableSorter<SALOMEDSImpl_AttributeTableOfReal> sorter( this, sortOrder, sortPolicy, theColumn, false );
00698     std::stable_sort( indices.begin(), indices.end(), sorter );
00699 
00700     if ( sortPolicy == EmptyIgnore ) {
00701       std::vector<int> other( myNbRows );
00702       cnt = 0;
00703       for( int i = 0; i < myNbRows; i++ )
00704        other[i] = HasValue(i+1, theColumn) ? indices[cnt++] : i+1;
00705       indices = other;
00706     }
00707     result = indices;
00708 
00709     for ( int row = 0; row < indices.size(); row++ ) {
00710       int idx = indices[row];
00711       if ( row+1 == idx ) continue;
00712       SwapRows(row+1, idx);
00713       int idx1 = 0;
00714       for ( int i = row+1; i < indices.size() && idx1 == 0; i++)
00715        if ( indices[i] == row+1 ) idx1 = i;
00716       indices[idx1] = idx;
00717     }
00718     // no need for SetModifyFlag(), since it is done by SwapRows()
00719   }
00720   return result;
00721 }
00722 
00723 void SALOMEDSImpl_AttributeTableOfReal::SwapCells(const int theRow1, const int theColumn1, 
00724                                             const int theRow2, const int theColumn2)
00725 {
00726   CheckLocked();  
00727   if (theRow1    > myNbRows    || theRow1 < 1)    throw DFexception("Invalid cell index");
00728   if (theRow2    > myNbRows    || theRow2 < 1)    throw DFexception("Invalid cell index");
00729   if (theColumn1 > myNbColumns || theColumn1 < 1) throw DFexception("Invalid cell index");
00730   if (theColumn2 > myNbColumns || theColumn2 < 1) throw DFexception("Invalid cell index");
00731 
00732   int anIndex1 = (theRow1-1)*myNbColumns + theColumn1;
00733   int anIndex2 = (theRow2-1)*myNbColumns + theColumn2;
00734 
00735   bool hasValue1 = myTable.find(anIndex1) != myTable.end();
00736   bool hasValue2 = myTable.find(anIndex2) != myTable.end();
00737 
00738   if (!hasValue1 && !hasValue2) return;                   // nothing changed
00739 
00740   double value1  = hasValue1 ? myTable[anIndex1] : 0;
00741   double value2  = hasValue2 ? myTable[anIndex2] : 0;
00742 
00743   if (hasValue1 && hasValue2 && value1 == value2) return; // nothing changed
00744 
00745   if (hasValue1) myTable[anIndex2] = value1;
00746   else           myTable.erase(anIndex2);
00747   if (hasValue2) myTable[anIndex1] = value2;
00748   else           myTable.erase(anIndex1);
00749 
00750   SetModifyFlag(); // table is modified
00751 }
00752 
00753 void SALOMEDSImpl_AttributeTableOfReal::SwapRows(const int theRow1, const int theRow2)
00754 {
00755   CheckLocked();  
00756   for (int i = 1; i <= myNbColumns; i++)
00757     SwapCells(theRow1, i, theRow2, i);
00758   // swap row titles
00759   std::string tmp = myRows[theRow1-1];
00760   myRows[theRow1-1] = myRows[theRow2-1];
00761   myRows[theRow2-1] = tmp;
00762   // no need for SetModifyFlag(), since it is done by SwapCells()
00763 }
00764 
00765 void SALOMEDSImpl_AttributeTableOfReal::SwapColumns(const int theColumn1, const int theColumn2)
00766 {
00767   CheckLocked();  
00768   for (int i = 1; i <= myNbRows; i++)
00769     SwapCells(i, theColumn1, i, theColumn2);
00770   // swap column titles
00771   std::string tmp = myCols[theColumn1-1];
00772   myCols[theColumn1-1] = myCols[theColumn2-1];
00773   myCols[theColumn2-1] = tmp;
00774   // no need for SetModifyFlag(), since it is done by SwapCells()
00775 }
00776