// Taken from UtiLite library r185 [www.utilite.googlecode.com] /* * utilite is a cross-platform library with * useful utilities for fast and small developing. * Copyright (C) 2010 Mathieu Labbe * * utilite is free library: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * utilite is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef USTL_H #define USTL_H #include #include #include #include #include #include /** * \file UStl.h * \brief Wrappers of STL for convenient functions. * * All functions you will find here are here * for the use of STL in a more convenient way. */ /** * Get unique keys from a std::multimap. * @param mm the multimap * @return the list which contains unique keys */ template inline std::list uUniqueKeys(const std::multimap & mm) { std::list l; typename std::list::reverse_iterator lastValue; for(typename std::multimap::const_iterator iter = mm.begin(); iter!=mm.end(); ++iter) { if(iter == mm.begin() || (iter != mm.begin() && *lastValue != iter->first)) { l.push_back(iter->first); lastValue = l.rbegin(); } } return l; } /** * Get all keys from a std::multimap. * @param mm the multimap * @return the list which contains all keys (may contains duplicated keys) */ template inline std::list uKeys(const std::multimap & mm) { std::list l; for(typename std::multimap::const_iterator iter = mm.begin(); iter!=mm.end(); ++iter) { l.push_back(iter->first); } return l; } /** * Get all values from a std::multimap. * @param mm the multimap * @return the list which contains all values (contains values from duplicated keys) */ template inline std::list uValues(const std::multimap & mm) { std::list l; for(typename std::multimap::const_iterator iter = mm.begin(); iter!=mm.end(); ++iter) { l.push_back(iter->second); } return l; } /** * Get values for a specified key from a std::multimap. * @param mm the multimap * @param key the key * @return the list which contains the values of the key */ template inline std::list uValues(const std::multimap & mm, const K & key) { std::list l; std::pair::const_iterator, typename std::multimap::const_iterator> range; range = mm.equal_range(key); for(typename std::multimap::const_iterator iter = range.first; iter!=range.second; ++iter) { l.push_back(iter->second); } return l; } /** * Get all keys from a std::map. * @param m the map * @return the vector of keys */ template inline std::vector uKeys(const std::map & m) { std::vector v(m.size()); int i=0; for(typename std::map::const_iterator iter = m.begin(); iter!=m.end(); ++iter) { v[i] = iter->first; ++i; } return v; } /** * Get all keys from a std::map. * @param m the map * @return the list of keys */ template inline std::list uKeysList(const std::map & m) { std::list l; for(typename std::map::const_iterator iter = m.begin(); iter!=m.end(); ++iter) { l.push_back(iter->first); } return l; } /** * Get all keys from a std::map. * @param m the map * @return the set of keys */ template inline std::set uKeysSet(const std::map & m) { std::set s; int i=0; for(typename std::map::const_iterator iter = m.begin(); iter!=m.end(); ++iter) { s.insert(s.end(), iter->first); ++i; } return s; } /** * Get all values from a std::map. * @param m the map * @return the vector of values */ template inline std::vector uValues(const std::map & m) { std::vector v(m.size()); int i=0; for(typename std::map::const_iterator iter = m.begin(); iter!=m.end(); ++iter) { v[i] = iter->second; ++i; } return v; } /** * Get all values from a std::map. * @param m the map * @return the list of values */ template inline std::list uValuesList(const std::map & m) { std::list l; for(typename std::map::const_iterator iter = m.begin(); iter!=m.end(); ++iter) { l.push_back(iter->second); } return l; } /** * Get the value of a specified key from a std::map. * @param m the map * @param key the key * @param defaultValue the default value used if the key is not found * @return the value */ template inline V uValue(const std::map & m, const K & key, const V & defaultValue = V()) { V v = defaultValue; typename std::map::const_iterator i = m.find(key); if(i != m.end()) { v = i->second; } return v; } /** * Get the value of a specified key from a std::map. This will * remove the value from the map; * @param m the map * @param key the key * @param defaultValue the default value used if the key is not found * @return the value */ template inline V uTake(std::map & m, const K & key, const V & defaultValue = V()) { V v; typename std::map::iterator i = m.find(key); if(i != m.end()) { v = i->second; m.erase(i); } else { v = defaultValue; } return v; } /** * Get the iterator at a specified position in a std::list. If the position * is out of range, the result is the end iterator of the list. * @param list the list * @param pos the index position in the list * @return the iterator at the specified index */ template inline typename std::list::iterator uIteratorAt(std::list & list, const unsigned int & pos) { typename std::list::iterator iter = list.begin(); for(unsigned int i = 0; i inline typename std::list::const_iterator uIteratorAt(const std::list & list, const unsigned int & pos) { typename std::list::const_iterator iter = list.begin(); for(unsigned int i = 0; i inline typename std::vector::iterator uIteratorAt(std::vector & v, const unsigned int & pos) { return v.begin() + pos; } /** * Get the value at a specified position in a std::list. If the position * is out of range, the result is undefined. * @param list the list * @param pos the index position in the list * @return the value at the specified index */ template inline V & uValueAt(std::list & list, const unsigned int & pos) { typename std::list::iterator iter = uIteratorAt(list, pos); return *iter; } /** * Get the value at a specified position in a std::list. If the position * is out of range, the result is undefined. * @param list the list * @param pos the index position in the list * @return the value at the specified index */ template inline const V & uValueAt(const std::list & list, const unsigned int & pos) { typename std::list::const_iterator iter = uIteratorAt(list, pos); return *iter; } /** * Check if the list contains the specified value. * @param list the list * @param value the value * @return true if the value is found in the list, otherwise false */ template inline bool uContains(const std::list & list, const V & value) { return std::find(list.begin(), list.end(), value) != list.end(); } /** * Check if the map contains the specified key. * @param map the map * @param key the key * @return true if the value is found in the map, otherwise false */ template inline bool uContains(const std::map & map, const K & key) { return map.find(key) != map.end(); } /** * Check if the multimap contains the specified key. * @param map the map * @param key the key * @return true if the value is found in the map, otherwise false */ template inline bool uContains(const std::multimap & map, const K & key) { return map.find(key) != map.end(); } /** * Insert an item in the map. Contrary to the insert in the STL, * if the key already exists, the value will be replaced by the new one. */ template inline void uInsert(std::map & map, const std::pair & pair) { std::pair::iterator, bool> inserted = map.insert(pair); if(inserted.second == false) { inserted.first->second = pair.second; } } /** * Convert a std::list to a std::vector. * @param list the list * @return the vector */ template inline std::vector uListToVector(const std::list & list) { return std::vector(list.begin(), list.end()); } /** * Convert a std::vector to a std::list. * @param v the vector * @return the list */ template inline std::list uVectorToList(const std::vector & v) { return std::list(v.begin(), v.end()); } /** * Append a list to another list. * @param list the list on which the other list will be appended * @param newItems the list of items to be appended */ template inline void uAppend(std::list & list, const std::list & newItems) { list.insert(list.end(), newItems.begin(), newItems.end()); } /** * Get the index in the list of the specified value. S negative index is returned * if the value is not found. * @param list the list * @param value the value * @return the index of the value in the list */ template inline int uIndexOf(const std::vector & list, const V & value) { int index=-1; int i=0; for(typename std::vector::const_iterator iter = list.begin(); iter!=list.end(); ++iter) { if(*iter == value) { index = i; break; } ++i; } return index; } /** * Split a string into multiple string around the specified separator. * Example: * @code * std::list v = split("Hello the world!", ' '); * @endcode * The list v will contain {"Hello", "the", "world!"} * @param str the string * @param separator the separator character * @return the list of strings */ inline std::list uSplit(const std::string & str, char separator = ' ') { std::list v; std::string buf; for(unsigned int i=0; i= '0' && c <= '9') */ inline bool uIsDigit(const char c) { return c >= '0' && c <= '9'; } /** * Split a string into number and character strings. * Example: * @code * std::list v = uSplit("Hello 03 my 65 world!"); * @endcode * The list v will contain {"Hello ", "03", " my ", "65", " world!"} * @param str the string * @return the list of strings */ inline std::list uSplitNumChar(const std::string & str) { std::list list; std::string buf; bool num = false; for(unsigned int i=0; ib */ inline int uStrNumCmp(const std::string & a, const std::string & b) { std::vector listA; std::vector listB; listA = uListToVector(uSplitNumChar(a)); listB = uListToVector(uSplitNumChar(b)); unsigned int i; int result = 0; for(i=0; i listA[i].size()) { result = -1; } else { result = listA[i].compare(listB[i]); } } else if(uIsDigit(listA[i].at(0))) { result = -1; } else if(uIsDigit(listB[i].at(0))) { result = 1; } else { result = listA[i].compare(listB[i]); } if(result != 0) { break; } } return result; } #endif /* USTL_H */