Isis 3.0 Developer's Reference (API) |
Home |
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 ©(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