diff options
author | Remko Tronçon <git@el-tramo.be> | 2011-05-02 20:05:08 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2011-05-02 20:19:31 (GMT) |
commit | 7d2074bc046c38cf6947da77e1b9610c1809217d (patch) | |
tree | 3ddb60ea83873023db964b8353c58ffb5d7df250 /Swiften/Base | |
parent | 68a93082f7ff8ede37112bf9c6cb34ad2986c6c8 (diff) | |
download | swift-contrib-7d2074bc046c38cf6947da77e1b9610c1809217d.zip swift-contrib-7d2074bc046c38cf6947da77e1b9610c1809217d.tar.bz2 |
Add a generic erase() algorithm.
Diffstat (limited to 'Swiften/Base')
-rw-r--r-- | Swiften/Base/Algorithm.h | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/Swiften/Base/Algorithm.h b/Swiften/Base/Algorithm.h new file mode 100644 index 0000000..f0c6b48 --- /dev/null +++ b/Swiften/Base/Algorithm.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <vector> +#include <list> +#include <map> +#include <algorithm> + +namespace Swift { + /* + * Generic erase() + */ + namespace Detail { + struct VectorCategory {}; + struct ListCategory {}; + struct MapCategory {}; + + template<typename T> + struct ContainerTraits {}; + + template<typename A, typename B> + struct ContainerTraits< std::vector<A, B> > { + typedef VectorCategory Category; + }; + + template<> + struct ContainerTraits< std::string > { + typedef VectorCategory Category; + }; + + template<typename A, typename B> + struct ContainerTraits< std::list<A, B> > { + typedef ListCategory Category; + }; + + template<typename A, typename B, typename C, typename D> + struct ContainerTraits< std::map<A, B, C, D> > { + typedef MapCategory Category; + }; + + template<typename C, typename V> + void eraseImpl(C& c, const V& v, VectorCategory) { + c.erase(std::remove(c.begin(), c.end(), v), c.end()); + } + + template<typename C, typename V> + void eraseImpl(C& c, const V& v, ListCategory) { + c.remove(v); + } + + template<typename C, typename V> + void eraseImpl(C& c, const V& v, MapCategory) { + for (typename C::iterator it = c.begin(); it != c.end(); ) { + if (it->second == v) { + c.erase(it++); + } + else { + ++it; + } + } + } + + template<typename C, typename P> + void eraseIfImpl(C& c, const P& p, MapCategory) { + for (typename C::iterator it = c.begin(); it != c.end(); ) { + if (p(*it)) { + c.erase(it++); + } + else { + ++it; + } + } + } + } + + template<typename C, typename V> + void erase(C& container, const V& value) { + Detail::eraseImpl(container, value, typename Detail::ContainerTraits<C>::Category()); + } + + template<typename C, typename P> + void eraseIf(C& container, const P& predicate) { + Detail::eraseIfImpl(container, predicate, typename Detail::ContainerTraits<C>::Category()); + } + + /* + * Functors + */ + template<typename K, typename V> + class PairSecondEquals { + public: + PairSecondEquals(const V& value) : value(value) { + } + + bool operator()(const std::pair<K,V>& pair) const { + return pair.second == value; + } + + private: + V value; + }; +} |