UtiLite  0.3.1
A lite utilities library
include/utilite/UStl.h
Go to the documentation of this file.
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 */
 All Classes Files Functions Variables Enumerations Friends Defines