MercuryDPM  Beta
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
BaseHandler.h
Go to the documentation of this file.
1 //Copyright (c) 2013-2014, The MercuryDPM Developers Team. All rights reserved.
2 //For the list of developers, see <http://www.MercuryDPM.org/Team>.
3 //
4 //Redistribution and use in source and binary forms, with or without
5 //modification, are permitted provided that the following conditions are met:
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above copyright
9 // notice, this list of conditions and the following disclaimer in the
10 // documentation and/or other materials provided with the distribution.
11 // * Neither the name MercuryDPM nor the
12 // names of its contributors may be used to endorse or promote products
13 // derived from this software without specific prior written permission.
14 //
15 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 //ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 //WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 //DISCLAIMED. IN NO EVENT SHALL THE MERCURYDPM DEVELOPERS TEAM BE LIABLE FOR ANY
19 //DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 //(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 //LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 //ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 //(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 //SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 
31 #ifndef BASEHANDLER_H
32 #define BASEHANDLER_H
33 
34 #include <iostream>
35 #include <vector>
36 #include "Math/Helpers.h"
37 #include "Logger.h"
38 
39 class DPMBase;
40 
49 template<class T>
51 {
52 public:
57  BaseHandler();
58 
62  BaseHandler(const BaseHandler<T>& BH);
63 
67  virtual ~BaseHandler();
68 
74 
78  template<typename U>
79  U* copyAndAddObject(const U& O);
80 
84  template<typename U>
85  U* copyAndAddObject(U* O);
86 
90  virtual void addObject(T* O);
91 
95  virtual void removeObject(unsigned const int id);
96 
100  void removeLastObject();
101 
105  void clear();
106 
111  virtual void readObject(std::istream& is) = 0;
112 
116  void read(std::istream& is);
117 
121  T* getObjectById(const unsigned int id);
122 
126  T* getObject(const unsigned int id);
127 
131  const T* getObject(const unsigned int id) const;
132 
136  T* getLastObject();
137 
141  const T* getLastObject() const;
142 
146  unsigned int getNumberOfObjects() const;
147 
151  unsigned int getStorageCapacity() const;
152 
156  void setStorageCapacity(const unsigned int N);
157 
161  const typename std::vector<T*>::const_iterator begin() const;
162 
166  const typename std::vector<T*>::iterator begin();
167 
171  const typename std::vector<T*>::const_iterator end() const;
172 
176  const typename std::vector<T*>::iterator end();
177 
181  void setDPMBase(DPMBase* DPMBase);
182 
186  DPMBase* getDPMBase();
187 
191  DPMBase* getDPMBase() const;
192 
196  virtual std::string getName() const = 0;
197 
198 protected:
205  std::vector<T*> objects_;
206 
207 private:
211  unsigned int maxObjects_;
212 
216  unsigned int nextId_;
217 
224  DPMBase* DPMBase_;
225 };
226 
230 template<class T> BaseHandler<T>::BaseHandler()
231 {
232  DPMBase_ = nullptr;
233  clear();
234  logger(DEBUG, "Basehandler<T>::BaseHandler() finished");
235 }
236 
244 template<class T> BaseHandler<T>::BaseHandler(const BaseHandler<T>& BH)
245 {
246  DPMBase_ = nullptr;
247  clear();
248  copyContentsFromOtherHandler(BH);
249  logger(DEBUG,"BaseHandler<T>::BaseHandler(const BaseHandler &BH) finished");
250 }
251 
252 template<class T> BaseHandler<T>::~BaseHandler()
253 {
254  clear();
255  logger(DEBUG, "BaseHandler<T>::~BaseHandler() finished");
256 }
257 
260 {
261  for (auto obj : BH.objects_)
262  {
263  addObject(obj->copy());
264  }
265 }
266 
268 template<class T> template<class U> U* BaseHandler<T>::copyAndAddObject(const U& O)
269 {
270  U* oCopy = O.copy();
271  addObject(oCopy);
272  return oCopy;
273 }
274 
276 template<class T> template<class U> U* BaseHandler<T>::copyAndAddObject(U* O)
277 {
278  U* oCopy = O->copy();
279  addObject(oCopy);
280  return oCopy;
281 }
282 
284 template<class T> void BaseHandler<T>::addObject(T* O)
285 {
286  objects_.push_back(O);
287  //Set the index of the particle
288  getLastObject()->setIndex(getNumberOfObjects() - 1);
289  //set the non changing particle identifier
290  getLastObject()->setId(nextId_);
291  //Update Id for next particle
292  nextId_++;
293  //Update the maximum number of Particles
294  if (getNumberOfObjects() > maxObjects_)
295  maxObjects_ = getNumberOfObjects();
296 }
297 
303 template<class T> void BaseHandler<T>::removeObject(unsigned const int index)
304 {
305  if (index >= getNumberOfObjects())
306  {
307  logger(ERROR, "In: void %::removeOject(const unsigned int index) const, no object exists with index %, number of objects is %", getName(), index, getNumberOfObjects());
308  return;
309  }
310 
311  //Okay, this function deletes the particle. Now, the problem is that
312  //particles store their position in the handler (@dducks: do they?)
313  //which means that we would absolutely destroy performance if we took
314  //something out in the middle. Now, what we'll do is swap our particle
315  //with the last one (in case it already is, it is invariant); then
316  //remove the last one.
317  //So, we want the last index.
318  std::size_t lastIndex = objects_.size() - 1;
319 
320  //So, step one, retrieve the pointer
321  T* objectToDelete = objects_[index];
322 
323  if (index != lastIndex) //Are we not the last object?
324  {
325  //well.. let's swap.
326  T* objectToMove = objects_[lastIndex];
327 
328  objects_[index] = objectToMove; //place it back
329  objects_[lastIndex] = objectToDelete; //Just to make sure.
330 
331  //and notify it of the change.
332  objects_[index]->moveInHandler(index);
333  //Even though we are going to delete this particle,
334  //we still need to keep it consistent.
335  objects_[lastIndex]->moveInHandler(lastIndex);
336  }
337 
338  //And _NOW_ we delete it.
339  delete objectToDelete;
340 
341  //And clear it from the backing container.
342  objects_.pop_back();
343 }
344 
345 template<class T> void BaseHandler<T>::removeLastObject()
346 {
347  if (getNumberOfObjects() == 0)
348  {
349  logger(WARN, "In: void %::removeLastObject, no Object exists in this BaseHandler.", getName());
350  return;
351  }
352  //Physically removes Object
353  delete objects_.back();
354  //Remove the (now double) reference to that last Object
355  objects_.pop_back();
356 }
357 
360 template<class T> void BaseHandler<T>::clear()
361 {
362 
363  for (auto obj : objects_)
364  {
365  delete obj;
366  }
367  objects_.clear();
368 
369  nextId_ = 0;
370  maxObjects_ = 0;
371 }
372 
374 template<class T> void BaseHandler<T>::read(std::istream& is)
375 {
376  clear();
377  unsigned int N;
378  std::string dummy;
379  is >> dummy;
380  std::stringstream line(std::stringstream::in | std::stringstream::out);
382  line >> N;
383  logger(VERBOSE, "In %::read(is): reading in % objects.", getName(), N);
384  for (unsigned int i = 0; i < N; i++)
385  {
386  readObject(is);
387  }
388 }
389 
394 template<class T> T* BaseHandler<T>::getObjectById(const unsigned int id)
395 {
396  // Usually, the id and the index into the backing storage matches
397  // So check this postion first!
398  // dducks: Can't we guarantee more? That should speed up searches.
399  if (id < objects_.size() && objects_[id]->getId() == id)
400  {
401  return objects_[id]; //There is a hit, return early
402  }
403 
404  for (T* obj : objects_ ) //Search for the correct id, since it wasn't where
405  { // we expected it. Just use a linear search..
406  if (obj->getId() == id) //Found it, so return!
407  return obj;
408  }
409  logger(ERROR, "[BaseHandler::getObjectById()] in Object* %: Object with ID % could not be found.", getName(), id);
410  return nullptr;
411 }
412 
415 template<class T> T* BaseHandler<T>::getObject(const unsigned int index)
416 {
417 #ifdef NDEBUG
418  return objects_[index];
419 #else
420  if (index >= getNumberOfObjects())
421  {
422  logger(ERROR, "[BaseHandler::getObject(const unsigned int index)] in Object* %: Object couldn't be found because index (%) is higher than number of objects.", getName(), index);
423  return nullptr;
424  }
425  else
426  {
427  return objects_[index];
428  }
429 #endif
430 }
431 
434 template<class T> const T* BaseHandler<T>::getObject(const unsigned int index) const
435 {
436 #ifdef NDEBUG
437  return objects_[index];
438 #else
439  if (index >= getNumberOfObjects())
440  {
441  logger(ERROR, "[BaseHandler::getObject(const unsigned int index) const] in Object* %: No object exist with index % number of objects is %", getName(), index, getNumberOfObjects());
442  return nullptr;
443  }
444  else
445  {
446  return objects_[index];
447  }
448 #endif
449 }
450 
452 template<class T> T* BaseHandler<T>::getLastObject()
453 {
454  return objects_.back();
455 }
456 
458 template<class T> const T* BaseHandler<T>::getLastObject() const
459 {
460  return objects_.back();
461 }
462 
464 template<class T> unsigned int BaseHandler<T>::getNumberOfObjects() const
465 {
466  return objects_.size();
467 }
468 
470 template<class T> unsigned int BaseHandler<T>::getStorageCapacity() const
471 {
472  return objects_.capacity();
473 }
474 
476 template<class T> void BaseHandler<T>::setStorageCapacity(const unsigned int N)
477 {
478  objects_.reserve(N);
479 }
480 
482 template<class T> const typename std::vector<T*>::const_iterator BaseHandler<T>::begin() const
483 {
484  return objects_.begin();
485 }
486 
488 template<class T> const typename std::vector<T*>::iterator BaseHandler<T>::begin()
489 {
490  return objects_.begin();
491 }
492 
494 template<class T> const typename std::vector<T*>::const_iterator BaseHandler<T>::end() const
495 {
496  return objects_.end();
497 }
498 
500 template<class T> const typename std::vector<T*>::iterator BaseHandler<T>::end()
501 {
502  return objects_.end();
503 }
504 
507 {
508  DPMBase_ = DPMBase;
509 }
510 
513 {
514 #ifdef NDEBUG
515  return DPMBase_;
516 #else
517  if (DPMBase_ == nullptr)
518  {
519  logger(ERROR, "[BaseHandler::getDPMBase()] in Object* %: pointer to DPMBase class is not set.", getName());
520  }
521  return DPMBase_;
522 #endif
523 }
524 
526 template<class T> DPMBase* BaseHandler<T>::getDPMBase() const
527 {
528 #ifdef NDEBUG
529  return DPMBase_;
530 #else
531  if (DPMBase_ == nullptr)
532  {
533  logger(ERROR, "[BaseHandler::getDPMBase() const] in Object* %: pointer to DPMBase class is not set.", getName());
534  }
535  return DPMBase_;
536 #endif
537 }
538 #endif
539 
The DPMBase header includes quite a few header files, defining all the handlers, which are essential...
Definition: DPMBase.h:61
virtual void readObject(std::istream &is)=0
Reads Object into the BaseHandler from restart data.
LL< Log::DEBUG > DEBUG
Debug information.
Definition: Logger.cc:31
Logger< MERCURY_LOGLEVEL > logger("MercuryKernel")
void setDPMBase(DPMBase *DPMBase)
Sets the problem that is solved using this handler.
Definition: BaseHandler.h:506
void setStorageCapacity(const unsigned int N)
Sets the storage capacity of this BaseHandler.
Definition: BaseHandler.h:476
T * getObjectById(const unsigned int id)
Gets a pointer to the Object at the specified index in the BaseHandler.
Definition: BaseHandler.h:394
unsigned int nextId_
identifier for next object created
Definition: BaseHandler.h:216
const std::vector< T * >::const_iterator end() const
Gets the end of the const_iterator over all BaseBoundary in this BaseHandler.
Definition: BaseHandler.h:494
void read(std::istream &is)
Reads all objects from restart data.
Definition: BaseHandler.h:374
LL< Log::ERROR > ERROR
Error log level.
Definition: Logger.cc:26
BaseHandler()
Default BaseHandler constructor, it creates an empty BaseHandler and assigns DPMBase_ to a null point...
Definition: BaseHandler.h:230
void removeLastObject()
Removes the last Object from the BaseHandler.
Definition: BaseHandler.h:345
const std::vector< T * >::const_iterator begin() const
Gets the begin of the const_iterator over all Object in this BaseHandler.
Definition: BaseHandler.h:482
LL< Log::WARN > WARN
Warning log level.
Definition: Logger.cc:27
U * copyAndAddObject(const U &O)
Creates a copy of a Object and adds it to the BaseHandler.
Definition: BaseHandler.h:268
void getLineFromStringStream(std::istream &in, std::stringstream &out)
Reads a line from one stringstream into another, and prepares the latter for reading in...
Definition: Helpers.cc:389
virtual void removeObject(unsigned const int id)
Removes an Object from the BaseHandler.
Definition: BaseHandler.h:303
T * getObject(const unsigned int id)
Gets a pointer to the Object at the specified index in the BaseHandler.
Definition: BaseHandler.h:415
virtual std::string getName() const =0
Gets the name of this handler.
virtual void addObject(T *O)
Adds a new Object to the BaseHandler.
Definition: BaseHandler.h:284
std::vector< T * > objects_
The actual list of Object pointers.
Definition: BaseHandler.h:205
Container to store the pointers to all objects that one creates in a simulation.
Definition: BaseHandler.h:50
LL< Log::VERBOSE > VERBOSE
Verbose information.
Definition: Logger.cc:30
unsigned int getNumberOfObjects() const
Gets the number of Object in this BaseHandler.
Definition: BaseHandler.h:464
DPMBase * DPMBase_
A pointer back to the DPMBase class.
Definition: BaseHandler.h:224
T * getLastObject()
Gets a pointer to the last Object in this BaseHandler.
Definition: BaseHandler.h:452
unsigned int getStorageCapacity() const
Gets the storage capacity of this BaseHandler.
Definition: BaseHandler.h:470
virtual ~BaseHandler()
Destructor, it destructs the BaseHandler and all Object it contains.
Definition: BaseHandler.h:252
void copyContentsFromOtherHandler(const BaseHandler< T > &BH)
Function that copies the contents (vector of pointers, maxObject_, nextId_, DPMBase_) from one handle...
Definition: BaseHandler.h:259
DPMBase * getDPMBase()
Gets the problem that is solved using this handler.
Definition: BaseHandler.h:512
unsigned int maxObjects_
An integer to keep track of the largest number of objects ever stored in this BaseHandler.
Definition: BaseHandler.h:211
void clear()
Empties the whole BaseHandler by removing all Objects and setting all other variables to 0...
Definition: BaseHandler.h:360