UtiLite
0.3.1
A lite utilities library
|
00001 /* 00002 * utilite is a cross-platform library with 00003 * useful utilities for fast and small developing. 00004 * Copyright (C) 2010 Mathieu Labbe 00005 * 00006 * utilite is free library: you can redistribute it and/or modify 00007 * it under the terms of the GNU Lesser General Public License as published by 00008 * the Free Software Foundation, either version 3 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * utilite is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public License 00017 * along with this program. If not, see <http://www.gnu.org/licenses/>. 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 00044 template<class K, class V> 00045 inline std::list<K> uUniqueKeys(const std::multimap<K, V> & mm) 00046 { 00047 std::list<K> l; 00048 typename std::list<K>::reverse_iterator lastValue; 00049 for(typename std::multimap<K, V>::const_iterator iter = mm.begin(); iter!=mm.end(); ++iter) 00050 { 00051 if(iter == mm.begin() || (iter != mm.begin() && *lastValue != iter->first)) 00052 { 00053 l.push_back(iter->first); 00054 lastValue = l.rbegin(); 00055 } 00056 } 00057 return l; 00058 } 00059 00065 template<class K, class V> 00066 inline std::vector<K> uKeys(const std::multimap<K, V> & mm) 00067 { 00068 std::vector<K> v(mm.size()); 00069 int i=0; 00070 for(typename std::multimap<K, V>::const_iterator iter = mm.begin(); iter!=mm.end(); ++iter) 00071 { 00072 v[i++] = iter->first; 00073 } 00074 return v; 00075 } 00076 00082 template<class K, class V> 00083 inline std::list<K> uKeysList(const std::multimap<K, V> & mm) 00084 { 00085 std::list<K> l; 00086 for(typename std::multimap<K, V>::const_iterator iter = mm.begin(); iter!=mm.end(); ++iter) 00087 { 00088 l.push_back(iter->first); 00089 } 00090 return l; 00091 } 00092 00098 template<class K, class V> 00099 inline std::vector<V> uValues(const std::multimap<K, V> & mm) 00100 { 00101 std::vector<V> v(mm.size()); 00102 int i=0; 00103 for(typename std::multimap<K, V>::const_iterator iter = mm.begin(); iter!=mm.end(); ++iter) 00104 { 00105 v[i++] = iter->second; 00106 } 00107 return v; 00108 } 00109 00115 template<class K, class V> 00116 inline std::list<V> uValuesList(const std::multimap<K, V> & mm) 00117 { 00118 std::list<V> l; 00119 for(typename std::multimap<K, V>::const_iterator iter = mm.begin(); iter!=mm.end(); ++iter) 00120 { 00121 l.push_back(iter->second); 00122 } 00123 return l; 00124 } 00125 00132 template<class K, class V> 00133 inline std::list<V> uValues(const std::multimap<K, V> & mm, const K & key) 00134 { 00135 std::list<V> l; 00136 std::pair<typename std::multimap<K, V>::const_iterator, typename std::multimap<K, V>::const_iterator> range; 00137 range = mm.equal_range(key); 00138 for(typename std::multimap<K, V>::const_iterator iter = range.first; iter!=range.second; ++iter) 00139 { 00140 l.push_back(iter->second); 00141 } 00142 return l; 00143 } 00144 00150 template<class K, class V> 00151 inline std::vector<K> uKeys(const std::map<K, V> & m) 00152 { 00153 std::vector<K> v(m.size()); 00154 int i=0; 00155 for(typename std::map<K, V>::const_iterator iter = m.begin(); iter!=m.end(); ++iter) 00156 { 00157 v[i] = iter->first; 00158 ++i; 00159 } 00160 return v; 00161 } 00162 00168 template<class K, class V> 00169 inline std::list<K> uKeysList(const std::map<K, V> & m) 00170 { 00171 std::list<K> l; 00172 for(typename std::map<K, V>::const_iterator iter = m.begin(); iter!=m.end(); ++iter) 00173 { 00174 l.push_back(iter->first); 00175 } 00176 return l; 00177 } 00178 00184 template<class K, class V> 00185 inline std::set<K> uKeysSet(const std::map<K, V> & m) 00186 { 00187 std::set<K> s; 00188 int i=0; 00189 for(typename std::map<K, V>::const_iterator iter = m.begin(); iter!=m.end(); ++iter) 00190 { 00191 s.insert(s.end(), iter->first); 00192 ++i; 00193 } 00194 return s; 00195 } 00196 00202 template<class K, class V> 00203 inline std::vector<V> uValues(const std::map<K, V> & m) 00204 { 00205 std::vector<V> v(m.size()); 00206 int i=0; 00207 for(typename std::map<K, V>::const_iterator iter = m.begin(); iter!=m.end(); ++iter) 00208 { 00209 v[i] = iter->second; 00210 ++i; 00211 } 00212 return v; 00213 } 00214 00220 template<class K, class V> 00221 inline std::list<V> uValuesList(const std::map<K, V> & m) 00222 { 00223 std::list<V> l; 00224 for(typename std::map<K, V>::const_iterator iter = m.begin(); iter!=m.end(); ++iter) 00225 { 00226 l.push_back(iter->second); 00227 } 00228 return l; 00229 } 00230 00238 template<class K, class V> 00239 inline V uValue(const std::map<K, V> & m, const K & key, const V & defaultValue = V()) 00240 { 00241 V v = defaultValue; 00242 typename std::map<K, V>::const_iterator i = m.find(key); 00243 if(i != m.end()) 00244 { 00245 v = i->second; 00246 } 00247 return v; 00248 } 00249 00258 template<class K, class V> 00259 inline V uTake(std::map<K, V> & m, const K & key, const V & defaultValue = V()) 00260 { 00261 V v; 00262 typename std::map<K, V>::iterator i = m.find(key); 00263 if(i != m.end()) 00264 { 00265 v = i->second; 00266 m.erase(i); 00267 } 00268 else 00269 { 00270 v = defaultValue; 00271 } 00272 return v; 00273 } 00274 00282 template<class V> 00283 inline typename std::list<V>::iterator uIteratorAt(std::list<V> & list, const unsigned int & pos) 00284 { 00285 typename std::list<V>::iterator iter = list.begin(); 00286 for(unsigned int i = 0; i<pos && iter != list.end(); ++i ) 00287 { 00288 ++iter; 00289 } 00290 return iter; 00291 } 00292 00300 template<class V> 00301 inline typename std::list<V>::const_iterator uIteratorAt(const std::list<V> & list, const unsigned int & pos) 00302 { 00303 typename std::list<V>::const_iterator iter = list.begin(); 00304 for(unsigned int i = 0; i<pos && iter != list.end(); ++i ) 00305 { 00306 ++iter; 00307 } 00308 return iter; 00309 } 00310 00318 template<class V> 00319 inline typename std::vector<V>::iterator uIteratorAt(std::vector<V> & v, const unsigned int & pos) 00320 { 00321 return v.begin() + pos; 00322 } 00323 00331 template<class V> 00332 inline V & uValueAt(std::list<V> & list, const unsigned int & pos) 00333 { 00334 typename std::list<V>::iterator iter = uIteratorAt(list, pos); 00335 return *iter; 00336 } 00337 00345 template<class V> 00346 inline const V & uValueAt(const std::list<V> & list, const unsigned int & pos) 00347 { 00348 typename std::list<V>::const_iterator iter = uIteratorAt(list, pos); 00349 return *iter; 00350 } 00351 00358 template<class V> 00359 inline bool uContains(const std::list<V> & list, const V & value) 00360 { 00361 return std::find(list.begin(), list.end(), value) != list.end(); 00362 } 00363 00370 template<class K, class V> 00371 inline bool uContains(const std::map<K, V> & map, const K & key) 00372 { 00373 return map.find(key) != map.end(); 00374 } 00375 00382 template<class K, class V> 00383 inline bool uContains(const std::multimap<K, V> & map, const K & key) 00384 { 00385 return map.find(key) != map.end(); 00386 } 00387 00392 template<class K, class V> 00393 inline void uInsert(std::map<K, V> & map, const std::pair<K, V> & pair) 00394 { 00395 std::pair<typename std::map<K, V>::iterator, bool> inserted = map.insert(pair); 00396 if(inserted.second == false) 00397 { 00398 inserted.first->second = pair.second; 00399 } 00400 } 00401 00407 template<class V> 00408 inline std::vector<V> uListToVector(const std::list<V> & list) 00409 { 00410 return std::vector<V>(list.begin(), list.end()); 00411 } 00412 00418 template<class V> 00419 inline std::list<V> uVectorToList(const std::vector<V> & v) 00420 { 00421 return std::list<V>(v.begin(), v.end()); 00422 } 00423 00429 template<class V> 00430 inline void uAppend(std::list<V> & list, const std::list<V> & newItems) 00431 { 00432 list.insert(list.end(), newItems.begin(), newItems.end()); 00433 } 00434 00442 template<class V> 00443 inline int uIndexOf(const std::vector<V> & list, const V & value) 00444 { 00445 int index=-1; 00446 int i=0; 00447 for(typename std::vector<V>::const_iterator iter = list.begin(); iter!=list.end(); ++iter) 00448 { 00449 if(*iter == value) 00450 { 00451 index = i; 00452 break; 00453 } 00454 ++i; 00455 } 00456 return index; 00457 } 00458 00470 inline std::list<std::string> uSplit(const std::string & str, char separator = ' ') 00471 { 00472 std::list<std::string> v; 00473 std::string buf; 00474 for(unsigned int i=0; i<str.size(); ++i) 00475 { 00476 if(str[i] != separator) 00477 { 00478 buf += str[i]; 00479 } 00480 else if(buf.size()) 00481 { 00482 v.push_back(buf); 00483 buf = ""; 00484 } 00485 } 00486 if(buf.size()) 00487 { 00488 v.push_back(buf); 00489 } 00490 return v; 00491 } 00492 00498 inline bool uIsDigit(const char c) 00499 { 00500 return c >= '0' && c <= '9'; 00501 } 00502 00513 inline std::list<std::string> uSplitNumChar(const std::string & str) 00514 { 00515 std::list<std::string> list; 00516 std::string buf; 00517 bool num = false; 00518 for(unsigned int i=0; i<str.size(); ++i) 00519 { 00520 if(uIsDigit(str[i])) 00521 { 00522 if(!num && buf.size()) 00523 { 00524 list.push_back(buf); 00525 buf.clear(); 00526 } 00527 buf += str[i]; 00528 num = true; 00529 } 00530 else 00531 { 00532 if(num) 00533 { 00534 list.push_back(buf); 00535 buf.clear(); 00536 } 00537 buf += str[i]; 00538 num = false; 00539 } 00540 } 00541 if(buf.size()) 00542 { 00543 list.push_back(buf); 00544 } 00545 return list; 00546 } 00547 00560 inline int uStrNumCmp(const std::string & a, const std::string & b) 00561 { 00562 std::vector<std::string> listA; 00563 std::vector<std::string> listB; 00564 00565 listA = uListToVector(uSplitNumChar(a)); 00566 listB = uListToVector(uSplitNumChar(b)); 00567 00568 unsigned int i; 00569 int result = 0; 00570 for(i=0; i<listA.size() && i<listB.size(); ++i) 00571 { 00572 if(uIsDigit(listA[i].at(0)) && uIsDigit(listB[i].at(0))) 00573 { 00574 //padding if zeros at the beginning 00575 if(listA[i].at(0) == '0' && listB[i].size() < listA[i].size()) 00576 { 00577 while(listB[i].size() < listA[i].size()) 00578 { 00579 listB[i] += '0'; 00580 } 00581 } 00582 else if(listB[i].at(0) == '0' && listA[i].size() < listB[i].size()) 00583 { 00584 while(listA[i].size() < listB[i].size()) 00585 { 00586 listA[i] += '0'; 00587 } 00588 } 00589 00590 if(listB[i].size() < listA[i].size()) 00591 { 00592 result = 1; 00593 } 00594 else if(listB[i].size() > listA[i].size()) 00595 { 00596 result = -1; 00597 } 00598 else 00599 { 00600 result = listA[i].compare(listB[i]); 00601 } 00602 } 00603 else if(uIsDigit(listA[i].at(0))) 00604 { 00605 result = -1; 00606 } 00607 else if(uIsDigit(listB[i].at(0))) 00608 { 00609 result = 1; 00610 } 00611 else 00612 { 00613 result = listA[i].compare(listB[i]); 00614 } 00615 00616 if(result != 0) 00617 { 00618 break; 00619 } 00620 } 00621 00622 return result; 00623 } 00624 00625 #endif /* USTL_H */