00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef USTL_H
00021 #define USTL_H
00022
00023 #include <list>
00024 #include <map>
00025 #include <set>
00026 #include <vector>
00027 #include <string>
00028 #include <algorithm>
00029 #include <stdlib.h>
00030
00045 template<class K, class V>
00046 inline std::list<K> uUniqueKeys(const std::multimap<K, V> & mm)
00047 {
00048 std::list<K> l;
00049 typename std::list<K>::reverse_iterator lastValue;
00050 for(typename std::multimap<K, V>::const_iterator iter = mm.begin(); iter!=mm.end(); ++iter)
00051 {
00052 if(iter == mm.begin() || (iter != mm.begin() && *lastValue != iter->first))
00053 {
00054 l.push_back(iter->first);
00055 lastValue = l.rbegin();
00056 }
00057 }
00058 return l;
00059 }
00060
00066 template<class K, class V>
00067 inline std::vector<K> uKeys(const std::multimap<K, V> & mm)
00068 {
00069 std::vector<K> v(mm.size());
00070 int i=0;
00071 for(typename std::multimap<K, V>::const_iterator iter = mm.begin(); iter!=mm.end(); ++iter)
00072 {
00073 v[i++] = iter->first;
00074 }
00075 return v;
00076 }
00077
00083 template<class K, class V>
00084 inline std::list<K> uKeysList(const std::multimap<K, V> & mm)
00085 {
00086 std::list<K> l;
00087 for(typename std::multimap<K, V>::const_iterator iter = mm.begin(); iter!=mm.end(); ++iter)
00088 {
00089 l.push_back(iter->first);
00090 }
00091 return l;
00092 }
00093
00099 template<class K, class V>
00100 inline std::vector<V> uValues(const std::multimap<K, V> & mm)
00101 {
00102 std::vector<V> v(mm.size());
00103 int i=0;
00104 for(typename std::multimap<K, V>::const_iterator iter = mm.begin(); iter!=mm.end(); ++iter)
00105 {
00106 v[i++] = iter->second;
00107 }
00108 return v;
00109 }
00110
00116 template<class K, class V>
00117 inline std::list<V> uValuesList(const std::multimap<K, V> & mm)
00118 {
00119 std::list<V> l;
00120 for(typename std::multimap<K, V>::const_iterator iter = mm.begin(); iter!=mm.end(); ++iter)
00121 {
00122 l.push_back(iter->second);
00123 }
00124 return l;
00125 }
00126
00133 template<class K, class V>
00134 inline std::list<V> uValues(const std::multimap<K, V> & mm, const K & key)
00135 {
00136 std::list<V> l;
00137 std::pair<typename std::multimap<K, V>::const_iterator, typename std::multimap<K, V>::const_iterator> range;
00138 range = mm.equal_range(key);
00139 for(typename std::multimap<K, V>::const_iterator iter = range.first; iter!=range.second; ++iter)
00140 {
00141 l.push_back(iter->second);
00142 }
00143 return l;
00144 }
00145
00151 template<class K, class V>
00152 inline std::vector<K> uKeys(const std::map<K, V> & m)
00153 {
00154 std::vector<K> v(m.size());
00155 int i=0;
00156 for(typename std::map<K, V>::const_iterator iter = m.begin(); iter!=m.end(); ++iter)
00157 {
00158 v[i] = iter->first;
00159 ++i;
00160 }
00161 return v;
00162 }
00163
00169 template<class K, class V>
00170 inline std::list<K> uKeysList(const std::map<K, V> & m)
00171 {
00172 std::list<K> l;
00173 for(typename std::map<K, V>::const_iterator iter = m.begin(); iter!=m.end(); ++iter)
00174 {
00175 l.push_back(iter->first);
00176 }
00177 return l;
00178 }
00179
00185 template<class K, class V>
00186 inline std::set<K> uKeysSet(const std::map<K, V> & m)
00187 {
00188 std::set<K> s;
00189 int i=0;
00190 for(typename std::map<K, V>::const_iterator iter = m.begin(); iter!=m.end(); ++iter)
00191 {
00192 s.insert(s.end(), iter->first);
00193 ++i;
00194 }
00195 return s;
00196 }
00197
00203 template<class K, class V>
00204 inline std::vector<V> uValues(const std::map<K, V> & m)
00205 {
00206 std::vector<V> v(m.size());
00207 int i=0;
00208 for(typename std::map<K, V>::const_iterator iter = m.begin(); iter!=m.end(); ++iter)
00209 {
00210 v[i] = iter->second;
00211 ++i;
00212 }
00213 return v;
00214 }
00215
00221 template<class K, class V>
00222 inline std::list<V> uValuesList(const std::map<K, V> & m)
00223 {
00224 std::list<V> l;
00225 for(typename std::map<K, V>::const_iterator iter = m.begin(); iter!=m.end(); ++iter)
00226 {
00227 l.push_back(iter->second);
00228 }
00229 return l;
00230 }
00231
00239 template<class K, class V>
00240 inline V uValue(const std::map<K, V> & m, const K & key, const V & defaultValue = V())
00241 {
00242 V v = defaultValue;
00243 typename std::map<K, V>::const_iterator i = m.find(key);
00244 if(i != m.end())
00245 {
00246 v = i->second;
00247 }
00248 return v;
00249 }
00250
00259 template<class K, class V>
00260 inline V uTake(std::map<K, V> & m, const K & key, const V & defaultValue = V())
00261 {
00262 V v;
00263 typename std::map<K, V>::iterator i = m.find(key);
00264 if(i != m.end())
00265 {
00266 v = i->second;
00267 m.erase(i);
00268 }
00269 else
00270 {
00271 v = defaultValue;
00272 }
00273 return v;
00274 }
00275
00283 template<class V>
00284 inline typename std::list<V>::iterator uIteratorAt(std::list<V> & list, const unsigned int & pos)
00285 {
00286 typename std::list<V>::iterator iter = list.begin();
00287 for(unsigned int i = 0; i<pos && iter != list.end(); ++i )
00288 {
00289 ++iter;
00290 }
00291 return iter;
00292 }
00293
00301 template<class V>
00302 inline typename std::list<V>::const_iterator uIteratorAt(const std::list<V> & list, const unsigned int & pos)
00303 {
00304 typename std::list<V>::const_iterator iter = list.begin();
00305 for(unsigned int i = 0; i<pos && iter != list.end(); ++i )
00306 {
00307 ++iter;
00308 }
00309 return iter;
00310 }
00311
00319 template<class V>
00320 inline typename std::set<V>::iterator uIteratorAt(std::set<V> & set, const unsigned int & pos)
00321 {
00322 typename std::set<V>::iterator iter = set.begin();
00323 for(unsigned int i = 0; i<pos && iter != set.end(); ++i )
00324 {
00325 ++iter;
00326 }
00327 return iter;
00328 }
00329
00337 template<class V>
00338 inline typename std::set<V>::const_iterator uIteratorAt(const std::set<V> & set, const unsigned int & pos)
00339 {
00340 typename std::set<V>::const_iterator iter = set.begin();
00341 for(unsigned int i = 0; i<pos && iter != set.end(); ++i )
00342 {
00343 ++iter;
00344 }
00345 return iter;
00346 }
00347
00355 template<class V>
00356 inline typename std::vector<V>::iterator uIteratorAt(std::vector<V> & v, const unsigned int & pos)
00357 {
00358 return v.begin() + pos;
00359 }
00360
00368 template<class V>
00369 inline typename std::vector<V>::const_iterator uIteratorAt(const std::vector<V> & v, const unsigned int & pos)
00370 {
00371 return v.begin() + pos;
00372 }
00373
00381 template<class V>
00382 inline V & uValueAt(std::list<V> & list, const unsigned int & pos)
00383 {
00384 typename std::list<V>::iterator iter = uIteratorAt(list, pos);
00385 return *iter;
00386 }
00387
00395 template<class V>
00396 inline const V & uValueAt(const std::list<V> & list, const unsigned int & pos)
00397 {
00398 typename std::list<V>::const_iterator iter = uIteratorAt(list, pos);
00399 return *iter;
00400 }
00401
00408 template<class V>
00409 inline bool uContains(const std::list<V> & list, const V & value)
00410 {
00411 return std::find(list.begin(), list.end(), value) != list.end();
00412 }
00413
00420 template<class K, class V>
00421 inline bool uContains(const std::map<K, V> & map, const K & key)
00422 {
00423 return map.find(key) != map.end();
00424 }
00425
00432 template<class K, class V>
00433 inline bool uContains(const std::multimap<K, V> & map, const K & key)
00434 {
00435 return map.find(key) != map.end();
00436 }
00437
00442 template<class K, class V>
00443 inline void uInsert(std::map<K, V> & map, const std::pair<K, V> & pair)
00444 {
00445 std::pair<typename std::map<K, V>::iterator, bool> inserted = map.insert(pair);
00446 if(inserted.second == false)
00447 {
00448 inserted.first->second = pair.second;
00449 }
00450 }
00451
00456 template<class K, class V>
00457 inline void uInsert(std::map<K, V> & map, const std::map<K, V> & items)
00458 {
00459 for(typename std::map<K, V>::const_iterator iter=items.begin(); iter!=items.end(); ++iter)
00460 {
00461 std::pair<typename std::map<K, V>::iterator, bool> inserted = map.insert(*iter);
00462 if(inserted.second == false)
00463 {
00464 inserted.first->second = iter->second;
00465 }
00466 }
00467 }
00468
00474 template<class V>
00475 inline std::vector<V> uListToVector(const std::list<V> & list)
00476 {
00477 return std::vector<V>(list.begin(), list.end());
00478 }
00479
00485 template<class V>
00486 inline std::list<V> uVectorToList(const std::vector<V> & v)
00487 {
00488 return std::list<V>(v.begin(), v.end());
00489 }
00490
00495 template<class K, class V>
00496 inline std::map<K, V> uMultimapToMap(const std::multimap<K, V> & m)
00497 {
00498 return std::map<K, V>(m.begin(), m.end());
00499 }
00500
00504 template<class K, class V>
00505 inline std::map<K, V> uMultimapToMapUnique(const std::multimap<K, V> & m)
00506 {
00507 std::map<K, V> mapOut;
00508 std::list<K> uniqueKeys = uUniqueKeys(m);
00509 for(typename std::list<K>::const_iterator iter = uniqueKeys.begin(); iter!=uniqueKeys.end(); ++iter)
00510 {
00511 if(m.count(*iter) == 1)
00512 {
00513 typename std::multimap<K, V>::const_iterator jter=m.find(*iter);
00514 mapOut.insert(mapOut.end(), std::pair<K,V>(jter->first, jter->second));
00515 }
00516 }
00517 return mapOut;
00518 }
00519
00525 template<class V>
00526 inline void uAppend(std::list<V> & list, const std::list<V> & newItems)
00527 {
00528 list.insert(list.end(), newItems.begin(), newItems.end());
00529 }
00530
00538 template<class V>
00539 inline int uIndexOf(const std::vector<V> & list, const V & value)
00540 {
00541 int index=-1;
00542 int i=0;
00543 for(typename std::vector<V>::const_iterator iter = list.begin(); iter!=list.end(); ++iter)
00544 {
00545 if(*iter == value)
00546 {
00547 index = i;
00548 break;
00549 }
00550 ++i;
00551 }
00552 return index;
00553 }
00554
00566 inline std::list<std::string> uSplit(const std::string & str, char separator = ' ')
00567 {
00568 std::list<std::string> v;
00569 std::string buf;
00570 for(unsigned int i=0; i<str.size(); ++i)
00571 {
00572 if(str[i] != separator)
00573 {
00574 buf += str[i];
00575 }
00576 else if(buf.size())
00577 {
00578 v.push_back(buf);
00579 buf = "";
00580 }
00581 }
00582 if(buf.size())
00583 {
00584 v.push_back(buf);
00585 }
00586 return v;
00587 }
00588
00603 inline std::string uJoin(const std::list<std::string> & strings, const std::string & separator = "")
00604 {
00605 std::string out;
00606 for(std::list<std::string>::const_iterator iter = strings.begin(); iter!=strings.end(); ++iter)
00607 {
00608 if(iter!=strings.begin() && !separator.empty())
00609 {
00610 out += separator;
00611 }
00612 out+=*iter;
00613 }
00614 return out;
00615 }
00616
00622 inline bool uIsDigit(const char c)
00623 {
00624 return c >= '0' && c <= '9';
00625 }
00626
00632 inline bool uIsInteger(const std::string & str, bool checkForSign = true)
00633 {
00634 bool isInteger = str.size()!=0;
00635 for(unsigned int i=0; i<str.size() && isInteger; ++i)
00636 {
00637 isInteger = (checkForSign && i==0 && str[i]=='-') || uIsDigit(str[i]);
00638 }
00639 return isInteger;
00640 }
00641
00647 inline bool uIsNumber(const std::string & str)
00648 {
00649 std::list<std::string> list = uSplit(str, '.');
00650 if(list.size() == 1)
00651 {
00652 return uIsInteger(str);
00653 }
00654 else if(list.size() == 2)
00655 {
00656 return uIsInteger(list.front()) && uIsInteger(list.back(), false);
00657 }
00658 return false;
00659 }
00660
00661
00672 inline std::list<std::string> uSplitNumChar(const std::string & str)
00673 {
00674 std::list<std::string> list;
00675 std::string buf;
00676 bool num = false;
00677 for(unsigned int i=0; i<str.size(); ++i)
00678 {
00679 if(uIsDigit(str[i]))
00680 {
00681 if(!num && buf.size())
00682 {
00683 list.push_back(buf);
00684 buf.clear();
00685 }
00686 buf += str[i];
00687 num = true;
00688 }
00689 else
00690 {
00691 if(num)
00692 {
00693 list.push_back(buf);
00694 buf.clear();
00695 }
00696 buf += str[i];
00697 num = false;
00698 }
00699 }
00700 if(buf.size())
00701 {
00702 list.push_back(buf);
00703 }
00704 return list;
00705 }
00706
00719 inline int uStrNumCmp(const std::string & a, const std::string & b)
00720 {
00721 std::vector<std::string> listA;
00722 std::vector<std::string> listB;
00723
00724 listA = uListToVector(uSplitNumChar(a));
00725 listB = uListToVector(uSplitNumChar(b));
00726
00727 unsigned int i;
00728 int result = 0;
00729 for(i=0; i<listA.size() && i<listB.size(); ++i)
00730 {
00731 if(uIsDigit(listA[i].at(0)) && uIsDigit(listB[i].at(0)))
00732 {
00733
00734 if(listA[i].at(0) == '0' && listB[i].size() < listA[i].size())
00735 {
00736 while(listB[i].size() < listA[i].size())
00737 {
00738 listB[i] += '0';
00739 }
00740 }
00741 else if(listB[i].at(0) == '0' && listA[i].size() < listB[i].size())
00742 {
00743 while(listA[i].size() < listB[i].size())
00744 {
00745 listA[i] += '0';
00746 }
00747 }
00748
00749 if(listB[i].size() < listA[i].size())
00750 {
00751 result = 1;
00752 }
00753 else if(listB[i].size() > listA[i].size())
00754 {
00755 result = -1;
00756 }
00757 else
00758 {
00759 result = listA[i].compare(listB[i]);
00760 }
00761 }
00762 else if(uIsDigit(listA[i].at(0)))
00763 {
00764 result = -1;
00765 }
00766 else if(uIsDigit(listB[i].at(0)))
00767 {
00768 result = 1;
00769 }
00770 else
00771 {
00772 result = listA[i].compare(listB[i]);
00773 }
00774
00775 if(result != 0)
00776 {
00777 break;
00778 }
00779 }
00780
00781 return result;
00782 }
00783
00787 inline bool uStrContains(const std::string & string, const std::string & substring)
00788 {
00789 return string.find(substring) != std::string::npos;
00790 }
00791
00792 inline int uCompareVersion(const std::string & version, int major, int minor=-1, int patch=-1)
00793 {
00794 std::vector<std::string> v = uListToVector(uSplit(version, '.'));
00795 if(v.size() == 3)
00796 {
00797 int vMajor = atoi(v[0].c_str());
00798 int vMinor = atoi(v[1].c_str());
00799 int vPatch = atoi(v[2].c_str());
00800 if(vMajor > major ||
00801 (vMajor == major && minor!=-1 && vMinor > minor) ||
00802 (vMajor == major && minor!=-1 && vMinor == minor && patch!=-1 && vPatch > patch))
00803 {
00804 return 1;
00805 }
00806 else if(vMajor == major && (minor == -1 || (vMinor == minor && (patch == -1 || vPatch == patch))))
00807 {
00808 return 0;
00809 }
00810 }
00811 return -1;
00812 }
00813
00814 #endif