USGS

Isis 3.0 Developer's Reference (API)

Home

CollectorMap.h

Go to the documentation of this file.
00001 #ifndef CollectorMap_h
00002 #define CollectorMap_h
00003 
00025 #include <cctype>
00026 #include <string>
00027 #include <map>
00028 #include <algorithm>
00029 #include <functional>
00030 #include <sstream>
00031 #include <iomanip>
00032 #include <exception>
00033 #include "iString.h"
00034 #include "iException.h"
00035 #include <gsl/gsl_math.h>
00036 
00037 
00038 namespace Isis {
00039 
00046   template <typename K> struct SimpleCompare {
00047 
00056     bool operator()(const K &v1, const K &v2) const {
00057       return (v1 < v2);
00058     }
00059 
00060   };
00061 
00069   template <typename K> struct NoCaseStringCompare {
00070 
00080     bool operator()(const K &v1, const K &v2) const {
00081       return (iString::DownCase(v1) < iString::DownCase(v2));
00082     }
00083 
00084   };
00085 
00093   template <typename K> struct RobustFloatCompare {
00094 
00103     bool operator()(const K &v1, const K &v2) const {
00104       return (gsl_fcmp(v1, v2, -1.0E-6) < 0);
00105     }
00106 
00107   };
00108 
00118   template <typename T> struct NoopRemoval {
00119     protected:
00120 
00126       void destroy(T *element) {
00127         return;
00128       }
00129 
00130   };
00131 
00139   template <typename T> struct PointerRemoval {
00140     protected:
00141 
00147       void destroy(T *element) {
00148         delete(*element);
00149         return;
00150       }
00151 
00152   };
00153 
00161   template <typename T> struct ArrayRemoval {
00162     protected:
00163 
00169       void destroy(T *element) {
00170         delete [](*element);
00171         return;
00172       }
00173 
00174   };
00175 
00176 
00187   template <typename T> struct DefaultCopy {
00188     protected:
00189 
00197       const T &copy(const T &src) const {
00198         return (src);
00199       }
00200 
00201   };
00202 
00203 
00219   template <typename T> struct PointerCopy {
00220     protected:
00231       T copy(const T &src)  const {
00232         return (allocate(*(src)));
00233       }
00234 
00235     private:
00243       template <typename P>
00244       P *allocate(const P &obj) const {
00245         return (new P(obj));
00246       }
00247   };
00248 
00249 
00250 
00417   template < typename K, typename T,
00418            template <class> class ComparePolicy = SimpleCompare,
00419            template <class> class RemovalPolicy = NoopRemoval,
00420            template <class> class CopyPolicy = DefaultCopy
00421            >
00422   class CollectorMap : public RemovalPolicy<T>, public CopyPolicy<T> {
00423     public:
00424       typedef T                                      CollectorType; 
00425 
00426       typedef std::multimap<K, CollectorType, ComparePolicy<K> > CollectorList;
00428       typedef typename CollectorList::iterator       CollectorIter;
00430       typedef typename CollectorList::const_iterator CollectorConstIter;
00431 
00439       enum KeyPolicy { UniqueKeys,     
00440                        DuplicateKeys   
00441                      };
00442 
00444       CollectorMap() : _keyPolicy(UniqueKeys) { }
00445 
00455       CollectorMap(const KeyPolicy &keyPolicy) : _keyPolicy(keyPolicy) { }
00456 
00462       virtual ~CollectorMap() {
00463         selfDestruct();
00464       }
00465 
00475       CollectorMap(const CollectorMap &cmap) {
00476         _keyPolicy = cmap._keyPolicy;
00477         CollectorConstIter cItr;
00478         for(cItr = cmap._list.begin() ; cItr != cmap._list.end() ; cItr++) {
00479           _list.insert(std::make_pair(cItr->first, cmap.copy(cItr->second)));
00480         }
00481       }
00482 
00496       CollectorMap &operator=(const CollectorMap &cmap) {
00497         if(&cmap != this) {
00498           selfDestruct();
00499           _keyPolicy = cmap._keyPolicy;
00500           CollectorConstIter cItr;
00501           for(cItr = cmap._list.begin() ; cItr != cmap._list.end() ; cItr++) {
00502             _list.insert(std::make_pair(cItr->first, cmap.copy(cItr->second)));
00503           }
00504         }
00505         return (*this);
00506       }
00507 
00513       int size() const {
00514         return (_list.size());
00515       }
00516 
00527       int count(const K &key) const {
00528         return (_list.count(key));
00529       }
00530 
00541       void add(const K &key, const T &value) {
00542         if(_keyPolicy == UniqueKeys) remove(key);
00543         _list.insert(std::make_pair(key, value));
00544         return;
00545       }
00546 
00552       bool exists(const K &key) const {
00553         CollectorConstIter cItr = _list.find(key);
00554         return (cItr != _list.end());
00555       }
00556 
00568       T &get(const K &key) throw(iException &) {
00569         CollectorIter cItr = _list.find(key);
00570         if(cItr == _list.end()) {
00571           std::string mess = "Requested value does not exist!";
00572           throw iException::Message(iException::Programmer, mess.c_str(), _FILEINFO_);
00573         }
00574         return (cItr->second);
00575       }
00576 
00582       const T &get(const K &key) const throw(iException &) {
00583         CollectorConstIter cItr = _list.find(key);
00584         if(cItr == _list.end()) {
00585           std::string mess = "Requested value does not exist!";
00586           throw iException::Message(iException::Programmer, mess.c_str(), _FILEINFO_);
00587         }
00588         return (cItr->second);
00589       }
00590 
00603       int index(const K &key) const {
00604         CollectorConstIter cItr = _list.lower_bound(key);
00605         if(cItr == _list.end()) {
00606           return (-1);
00607         }
00608         else {
00609           return (std::distance(_list.begin(), cItr));
00610         }
00611       }
00612 
00623       T &getNth(int nth) throw(iException &) {
00624         CollectorIter cItr;
00625         int i;
00626         for(cItr = _list.begin(), i = 0 ; cItr != _list.end() ; ++cItr, i++) {
00627           if(i == nth) break;
00628         }
00629 
00630         if(cItr == _list.end()) {
00631           std::ostringstream mess;
00632           mess << "Requested index (" << nth << ") out of range" << std::endl;
00633           throw iException::Message(iException::Programmer, mess.str(), _FILEINFO_);
00634         }
00635         return (cItr->second);
00636       }
00637 
00648       const T &getNth(int nth) const throw(iException &) {
00649         CollectorConstIter cItr;
00650         int i;
00651         for(cItr = _list.begin(), i = 0 ; cItr != _list.end() ; ++cItr, i++) {
00652           if(i == nth) break;
00653         }
00654         if(cItr == _list.end()) {
00655           std::ostringstream mess;
00656           mess << "Requested index (" << nth << ") out of range" << std::endl;
00657           throw iException::Message(iException::Programmer, mess.str(), _FILEINFO_);
00658         }
00659         return (cItr->second);
00660       }
00661 
00672       const K &key(int nth) const throw(iException &) {
00673         CollectorConstIter cItr;
00674         int i;
00675         for(cItr = _list.begin(), i = 0 ; cItr != _list.end() ; ++cItr, i++) {
00676           if(i == nth) break;
00677         }
00678         if(cItr == _list.end()) {
00679           std::ostringstream mess;
00680           mess << "Requested key index (" << nth << ") out of range" << std::endl;
00681           throw iException::Message(iException::Programmer, mess.str(), _FILEINFO_);
00682         }
00683         return (cItr->first);
00684       }
00685 
00693       int remove(const K &key) {
00694         CollectorIter Itr1 = _list.lower_bound(key);
00695         if(Itr1 == _list.end()) return (0);
00696 
00697         CollectorIter Itr2 = _list.upper_bound(key);
00698         while(Itr1 != Itr2) {
00699           destroy(&Itr1->second);
00700           ++Itr1;
00701         }
00702         return (_list.erase(key));
00703       }
00704 
00710       CollectorConstIter begin() const {
00711         return _list.begin();
00712       }
00713 
00719       CollectorConstIter end() const {
00720         return _list.end();
00721       }
00722 
00728       CollectorIter begin() {
00729         return _list.begin();
00730       }
00731 
00738       CollectorIter end() {
00739         return _list.end();
00740       }
00741 
00742     private:
00743       KeyPolicy      _keyPolicy;  
00744       CollectorList  _list;       
00745 
00753       void selfDestruct() {
00754         CollectorIter itr;
00755         for(itr = _list.begin() ; itr != _list.end() ; itr++) {
00756           destroy(&itr->second);
00757         }
00758         _list.clear();
00759       }
00760 
00761 
00762   };
00763 
00764 };
00765 #endif
00766 
00767