• Main Page
  • Classes
  • Files
  • File List

Swiften/Base/Algorithm.h

00001 /*
00002  * Copyright (c) 2011 Remko Tronçon
00003  * Licensed under the GNU General Public License v3.
00004  * See Documentation/Licenses/GPLv3.txt for more information.
00005  */
00006 
00007 #pragma once
00008 
00009 #include <vector>
00010 #include <list>
00011 #include <map>
00012 #include <algorithm>
00013 
00014 namespace Swift {
00015 
00016   /*
00017    * Generic erase()
00018    */
00019   namespace Detail {
00020     struct VectorCategory {};
00021     struct ListCategory {};
00022     struct MapCategory {};
00023 
00024     template<typename T> 
00025     struct ContainerTraits;
00026 
00027     template<typename A, typename B> 
00028     struct ContainerTraits< std::vector<A, B> > {
00029       typedef VectorCategory Category;
00030     };
00031 
00032     template<>
00033     struct ContainerTraits< std::string > {
00034       typedef VectorCategory Category;
00035     };
00036 
00037     template<typename A, typename B> 
00038     struct ContainerTraits< std::list<A, B> > {
00039       typedef ListCategory Category;
00040     };
00041 
00042     template<typename A, typename B, typename C, typename D> 
00043     struct ContainerTraits< std::map<A, B, C, D> > {
00044       typedef MapCategory Category;
00045     };
00046 
00047     template<typename C, typename V>
00048     void eraseImpl(C& c, const V& v, VectorCategory) {
00049       c.erase(std::remove(c.begin(), c.end(), v), c.end());
00050     }
00051 
00052     template<typename C, typename V>
00053     void eraseImpl(C& c, const V& v, ListCategory) {
00054       c.remove(v);
00055     }
00056 
00057     template<typename C, typename V>
00058     void eraseImpl(C& c, const V& v, MapCategory) {
00059       for (typename C::iterator it = c.begin(); it != c.end(); ) {
00060         if (it->second == v) {
00061           c.erase(it++);
00062         }
00063         else {
00064           ++it;
00065         }
00066       }
00067     }
00068 
00069     template<typename C, typename P>
00070     void eraseIfImpl(C& c, const P& p, MapCategory) {
00071       for (typename C::iterator it = c.begin(); it != c.end(); ) {
00072         if (p(*it)) {
00073           c.erase(it++);
00074         }
00075         else {
00076           ++it;
00077         }
00078       }
00079     }
00080     
00081     template<typename C, typename P>
00082     void eraseIfImpl(C& c, const P& p, VectorCategory) {
00083       c.erase(std::remove_if(c.begin(), c.end(), p), c.end());
00084     }
00085   }
00086 
00087   template<typename C, typename V>
00088   void erase(C& container, const V& value) {
00089     Detail::eraseImpl(container, value, typename Detail::ContainerTraits<C>::Category());
00090   }
00091 
00092   template<typename C, typename P>
00093   void eraseIf(C& container, const P& predicate) {
00094     Detail::eraseIfImpl(container, predicate, typename Detail::ContainerTraits<C>::Category());
00095   }
00096 
00097   template<typename Source, typename Target>
00098   void append(Target& target, const Source& source) {
00099     target.insert(target.end(), source.begin(), source.end());
00100   }
00101 
00102   template<typename A, typename B, typename C, typename D> 
00103   B get(const std::map<A, B, C, D>& map, const A& key, const B& defaultValue) {
00104     typename std::map<A, B, C, D>::const_iterator i = map.find(key);
00105     if (i != map.end()) {
00106       return i->second;
00107     }
00108     else {
00109       return defaultValue;
00110     }
00111   }
00112 
00113   template<typename Container>
00114   void safeClear(Container& c) {
00115     std::fill(c.begin(), c.end(), 0);
00116     c.clear();
00117   }
00118 
00119   /*
00120    * Functors
00121    */
00122   template<typename K, typename V>
00123   class PairFirstEquals {
00124     public:
00125       PairFirstEquals(const K& value) : value(value) {
00126       }
00127 
00128       bool operator()(const std::pair<K,V>& pair) const {
00129         return pair.first == value;
00130       }
00131 
00132     private:
00133       K value;
00134   };
00135 
00136   template<typename K, typename V>
00137   class PairSecondEquals {
00138     public:
00139       PairSecondEquals(const V& value) : value(value) {
00140       }
00141 
00142       bool operator()(const std::pair<K,V>& pair) const {
00143         return pair.second == value;
00144       }
00145 
00146     private:
00147       V value;
00148   };
00149 }

Generated on Fri Oct 12 2012 21:00:19 for Swiften by  doxygen 1.7.1