Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

ArrayOfTaggedObjects.cpp

Go to the documentation of this file.
00001 /* ****************************************************************** **
00002 **    OpenSees - Open System for Earthquake Engineering Simulation    **
00003 **          Pacific Earthquake Engineering Research Center            **
00004 **                                                                    **
00005 **                                                                    **
00006 ** (C) Copyright 1999, The Regents of the University of California    **
00007 ** All Rights Reserved.                                               **
00008 **                                                                    **
00009 ** Commercial use of this program without express permission of the   **
00010 ** University of California, Berkeley, is strictly prohibited.  See   **
00011 ** file 'COPYRIGHT'  in main directory for information on usage and   **
00012 ** redistribution,  and for a DISCLAIMER OF ALL WARRANTIES.           **
00013 **                                                                    **
00014 ** Developed by:                                                      **
00015 **   Frank McKenna (fmckenna@ce.berkeley.edu)                         **
00016 **   Gregory L. Fenves (fenves@ce.berkeley.edu)                       **
00017 **   Filip C. Filippou (filippou@ce.berkeley.edu)                     **
00018 **                                                                    **
00019 ** ****************************************************************** */
00020                                                                         
00021 // $Revision: 1.1.1.1 $
00022 // $Date: 2000/09/15 08:23:30 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/tagged/storage/ArrayOfTaggedObjects.cpp,v $
00024                                                                         
00025                                                                         
00026 // File: ~/tagged/storage/ArrayOfTaggedObjects.C
00027 //
00028 // Written: fmk 
00029 // Created: 11/96
00030 // Revision: A
00031 //
00032 // Purpose: This file contains the implementation of the ArrayOfTaggedObjects
00033 // class.
00034 //
00035 // What: "@(#) ArrayOfTaggedObjects.C, revA"
00036 
00037 #include <TaggedObject.h>
00038 #include <ArrayOfTaggedObjects.h>
00039 
00040 #include <G3Globals.h>
00041 
00042 ArrayOfTaggedObjects::ArrayOfTaggedObjects(int size)
00043 :numComponents(0),sizeComponentArray(0), positionLastEntry(0),
00044  positionLastNoFitEntry(0),fitFlag(true), theComponents(0),
00045  myIter(*this)
00046 {
00047     // get the components array from the heap
00048     theComponents = new TaggedObject *[size];
00049     
00050     // check we obtained enough memory and set the array size
00051     if (theComponents == 0) {
00052  g3ErrorHandler->warning("%s %s %d\n",
00053     "ArrayOfTaggedObjects::ArrayOfTaggedObjects - ",
00054     "failed to allocate an array of size",
00055     size);
00056  sizeComponentArray = 0;
00057     } else 
00058  sizeComponentArray = size;
00059 
00060     // 0 the array 
00061     for (int i=0; i<sizeComponentArray; i++) 
00062  theComponents[i] = 0;
00063 }
00064 
00065 
00066 ArrayOfTaggedObjects::~ArrayOfTaggedObjects()
00067 {
00068     if (theComponents != 0)
00069  delete [] theComponents;
00070 }
00071 
00072 
00073 
00074 int
00075 ArrayOfTaggedObjects::setSize(int newSize)
00076 {
00077     // check a valid size
00078     if (newSize < 0 && newSize > sizeComponentArray) {
00079  g3ErrorHandler->warning("ArrayOfTaggedObjects::setSize - invalid size %d\n",
00080     newSize);
00081  return -1; 
00082     } 
00083 
00084     if (newSize < 2) newSize = 2; // make 2 the min size;
00085     
00086     // get an array of pointers from the heap
00087     // NOTE: cannot use TaggedObject **newArray = new (TaggedObject *)[newSize]; 
00088     // with digital cxx compiler!!!!
00089     TaggedObject **newArray = new TaggedObject *[newSize]; 
00090 
00091     if (newArray == 0) {
00092  // cannot increase size to newSize, keep as is and return error
00093  g3ErrorHandler->warning("ArrayOfTaggedObjects::setSize - %s %d\n",
00094     "failed to allocate an array of size ",
00095     newSize);
00096  return -2;
00097     } 
00098 
00099     // 
00100     // we got the space we needed .. now we populate the new array
00101     // trying to put everything in nicely, i.e. in location given by obj tags.
00102     //
00103     
00104     // first zero the new array
00105     for (int i=0; i<newSize; i++) 
00106  newArray[i] = 0;
00107 
00108     // store the needed info of the old array 
00109     TaggedObject **oldArray = theComponents;
00110     int oldArrayLastEntry = positionLastEntry;
00111 
00112     // set data for new aray
00113     theComponents = newArray;
00114     sizeComponentArray = newSize;  
00115 
00116     int error = 0;
00117     if (fitFlag == true && positionLastEntry <= newSize) { 
00118  // we will copy old to new directly 
00119  // as all fitted well last time this is just a straight assignment
00120  
00121  theComponents = newArray;
00122  sizeComponentArray = newSize; 
00123  for (int i=0; i<=positionLastEntry; i++)
00124      theComponents[i] = oldArray[i];
00125     } else { 
00126  // we will see if the components fit in well this time
00127 
00128  // reset the parameters for the new array 
00129  numComponents = 0;
00130  sizeComponentArray = newSize;
00131  positionLastEntry = 0;
00132  positionLastNoFitEntry = 0;
00133  fitFlag = true;
00134 
00135  // now add all the componets of the old array into the new one
00136  // we add using addComponent() to see if false fitFlag will now be true
00137  for (int j=0; j<=oldArrayLastEntry; j++)
00138      if (oldArray[j] != 0)
00139   if (this->addComponent(oldArray[j]) == false) {
00140       // this should never happen - but in case it does
00141       g3ErrorHandler->warning("%s %s %d\n",
00142           "SERIOUS ERROR: ArrayOfTaggedObjects::setSize() - ",
00143           "we have lost a component with tag: ",
00144           oldArray[j]->getTag());
00145       error = -3;
00146   }    
00147     }
00148 
00149     // delete the old array
00150     if (oldArray != 0)
00151  delete [] oldArray;
00152     
00153     return error;
00154 }
00155 
00156 
00157 bool 
00158 ArrayOfTaggedObjects::addComponent(TaggedObject *newComponent)
00159 {
00160     // check to see that no other component already exists
00161 //    if (allowMultiple == false) {
00162  TaggedObject *other = this->getComponentPtr(newComponent->getTag());
00163  if (other != 0) {
00164      g3ErrorHandler->warning("%s %s %d\n",     
00165         "WARNING ArrayOfTaggedObjects::addComponent() - component",
00166         " with tag already exists, not adding component with tag: ",
00167         newComponent->getTag());
00168      return false;
00169  }
00170 //    }
00171     
00172     // check to see if size of current array is big enough. if not resize.
00173     if (numComponents == sizeComponentArray) 
00174  if (this->setSize(2*numComponents) < 0) {
00175      g3ErrorHandler->warning("%s %s %d\n",          
00176          "ArrayOfTaggedObjects::addComponent() ",
00177          "- failed to enlarge the array with size",
00178          2*numComponents);
00179      return false;
00180  }
00181     
00182     // we try to the Component in nicely, i.e. in
00183     // position given by the newComponents Tag
00184 
00185     int newComponentTag = newComponent->getTag();
00186     
00187     if ((newComponentTag >= 0) && (newComponentTag < sizeComponentArray)) {
00188  if (theComponents[newComponentTag] == 0)   { // it will go in nicely
00189      theComponents[newComponentTag] = newComponent;
00190      numComponents ++;
00191      if (newComponentTag > positionLastEntry)
00192   positionLastEntry = newComponentTag;
00193      return true;
00194  }
00195     }
00196 
00197     // it won't go in nicely, so put wherever we can get it in
00198     while (theComponents[positionLastNoFitEntry] != 0 && 
00199     positionLastNoFitEntry < sizeComponentArray )
00200  positionLastNoFitEntry++;
00201 
00202     // just in case we don't get a location ..  though we should!!
00203     if (positionLastNoFitEntry == sizeComponentArray) {
00204  g3ErrorHandler->warning("%s %s",
00205     "ArrayOfTaggedObjects::addComponent() - could not ",
00206     "- find a vacant spot after enlarging!!\n");
00207  return false;
00208     }
00209  
00210     theComponents[positionLastNoFitEntry] = newComponent;
00211     numComponents++;
00212     if (positionLastNoFitEntry > positionLastEntry)
00213  positionLastEntry = positionLastNoFitEntry;
00214     fitFlag = false;
00215 
00216     return true;  // o.k.
00217 }
00218 
00219 TaggedObject *
00220 ArrayOfTaggedObjects::removeComponent(int tag)
00221 {
00222     TaggedObject *removed;
00223     
00224     // first check to see if object is located at pos given by tag
00225     if ((tag >= 0) && (tag < sizeComponentArray))
00226  
00227  // if all objects in nicely then has to be at location given by tag
00228  if (fitFlag == true) { 
00229      removed = theComponents[tag];
00230      theComponents[tag] = 0;
00231 
00232      // if the object is there decrement numComponents added and 
00233      // check if need to reset positionLastEntry marker
00234      if (removed != 0) {
00235   numComponents--;       
00236   
00237   if (positionLastEntry == tag) {
00238       for (int i = positionLastEntry; i>=0; i--)
00239    if (theComponents[i] != 0) {
00240        positionLastEntry = i;
00241        i = -1; // break out of loop
00242    }
00243   }
00244      }
00245      return removed;
00246  }  else  // it still may be at nice location so do as above
00247      if (theComponents[tag] != 0)
00248   if ((theComponents[tag]->getTag()) == tag) {
00249       removed = theComponents[tag];      
00250       theComponents[tag] = 0;
00251       if (positionLastEntry == tag) {
00252    for (int i = positionLastEntry; i>=0; i--)
00253        if (theComponents[i] != 0) {
00254     positionLastEntry = i;
00255     i = -1; // break out of loop
00256        }
00257       }      
00258       positionLastNoFitEntry = 0;
00259       numComponents--;      
00260       return removed;
00261   }
00262 
00263     // else we have to look through array until we find it or 
00264     // reach lastPosition used
00265     for (int i=0; i<=positionLastEntry; i++)
00266  if (theComponents[i] != 0)
00267      if (theComponents[i]->getTag() == tag) {
00268   
00269   // we found the component so do as above again
00270   // and then return a pointer to the component
00271   removed = theComponents[i];
00272   theComponents[i] = 0;
00273   if (positionLastEntry == i) {
00274       for (int j = positionLastEntry; j>=0; j--)
00275    if (theComponents[j] != 0) {
00276        positionLastEntry = j;
00277        j = -1; // break out of loop
00278    }
00279   }        
00280   positionLastNoFitEntry = 0;
00281   numComponents--;
00282   return removed;
00283      }
00284 
00285     // if get here the object is not stored in the array
00286     return 0;
00287 }
00288 
00289 int
00290 ArrayOfTaggedObjects::getNumComponents(void) const
00291 {
00292     return numComponents;
00293 }
00294 
00295 TaggedObject *
00296 ArrayOfTaggedObjects::getComponentPtr(int tag)
00297 {
00298 
00299     // first check it's not where we would like it
00300     if ((tag >= 0) && (tag < sizeComponentArray))
00301  if (fitFlag == true) // either its at nice position or not entered
00302      return theComponents[tag];
00303  else {             // it still may be at nice location
00304      if (theComponents[tag] != 0)
00305   if ((theComponents[tag]->getTag()) == tag)
00306       return theComponents[tag];
00307  }
00308 
00309     // else we have to look through array until we find it or 
00310     // reach lastPosition used
00311     for (int i=0; i<=positionLastEntry; i++)
00312  if (theComponents[i] != 0)
00313      if (theComponents[i]->getTag() == tag) 
00314   return theComponents[i];
00315 
00316     // its not in the array
00317     return 0;
00318 }
00319 
00320 
00321 TaggedObjectIter &
00322 ArrayOfTaggedObjects::getComponents()
00323 {
00324     // reset the iter to point to first component and then return 
00325     // a reference to the iter
00326     myIter.reset();
00327     return myIter;
00328 }
00329 
00330 
00331 ArrayOfTaggedObjectsIter 
00332 ArrayOfTaggedObjects::getIter()
00333 {
00334     // return a new iter to the components, more expensive to use
00335     // this iter as two memory calls to heap .. needed if user needs
00336     // to have multiple iters running in same code segment!
00337     return ArrayOfTaggedObjectsIter(*this);
00338 }
00339 
00340 
00341 TaggedObjectStorage *
00342 ArrayOfTaggedObjects::getEmptyCopy(void)
00343 {
00344     ArrayOfTaggedObjects *theCopy = new ArrayOfTaggedObjects(sizeComponentArray);
00345     
00346     if (theCopy == 0) {
00347  g3ErrorHandler->warning("ArrayOfTaggedObjects::getEmptyCopy - %s\n",
00348     "out of memory");
00349     }
00350 
00351     return theCopy;
00352 }
00353 
00354 void
00355 ArrayOfTaggedObjects::clearAll(bool invokeDestructors)
00356 {
00357     if (invokeDestructors == true) {
00358  // go through and invoke the components object destructors
00359  // and set the array pointers to 0
00360  for (int i=0; i<=positionLastEntry; i++) {
00361      if (theComponents[i] != 0) {
00362   delete theComponents[i];
00363   theComponents[i] = 0;
00364      }
00365  }
00366     } else {
00367  // just set the array pointers to 0
00368  for (int i=0; i<=positionLastEntry; i++) {
00369      if (theComponents[i] != 0) {
00370   theComponents[i] = 0;
00371      }
00372  }
00373     }
00374     
00375     positionLastEntry = 0;
00376     positionLastNoFitEntry = 0;
00377     fitFlag = true;
00378     numComponents = 0;
00379 }
00380 
00381 
00382 
00383 
00384 // void Print(ostream &s, int flag) const
00385 // method which invokes Print on all components
00386 
00387 void
00388 ArrayOfTaggedObjects::Print(ostream &s, int flag)
00389 {
00390     // go through the array invoking Print on non-zero entries
00391     for (int i=0; i<=positionLastEntry; i++)
00392  if (theComponents[i] != 0)
00393      theComponents[i]->Print(s, flag);
00394 }
00395 
00396 
00397 
Copyright Contact Us