summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/Base/Algorithm.h')
-rw-r--r--Swiften/Base/Algorithm.h319
1 files changed, 176 insertions, 143 deletions
diff --git a/Swiften/Base/Algorithm.h b/Swiften/Base/Algorithm.h
index d5edab1..ee761b7 100644
--- a/Swiften/Base/Algorithm.h
+++ b/Swiften/Base/Algorithm.h
@@ -1,154 +1,187 @@
/*
- * Copyright (c) 2011 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2011-2018 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#pragma once
-#include <vector>
+#include <algorithm>
#include <list>
#include <map>
-#include <algorithm>
+#include <string>
+#include <vector>
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 P>
- void eraseIfImpl(C& c, const P& p, VectorCategory) {
- c.erase(std::remove_if(c.begin(), c.end(), p), c.end());
- }
- }
-
- 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());
- }
-
- template<typename Source, typename Target>
- void append(Target& target, const Source& source) {
- target.insert(target.end(), source.begin(), source.end());
- }
-
- template<typename Source, typename Target>
- void assign(Target& target, const Source& source) {
- target.assign(source.begin(), source.end());
- }
-
- template<typename A, typename B, typename C, typename D>
- B get(const std::map<A, B, C, D>& map, const A& key, const B& defaultValue) {
- typename std::map<A, B, C, D>::const_iterator i = map.find(key);
- if (i != map.end()) {
- return i->second;
- }
- else {
- return defaultValue;
- }
- }
-
- template<typename Container>
- void safeClear(Container& c) {
- std::fill(c.begin(), c.end(), 0);
- c.clear();
- }
-
- /*
- * Functors
- */
- template<typename K, typename V>
- class PairFirstEquals {
- public:
- PairFirstEquals(const K& value) : value(value) {
- }
-
- bool operator()(const std::pair<K,V>& pair) const {
- return pair.first == value;
- }
-
- private:
- K value;
- };
-
- 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;
- };
+ /*
+ * 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 P>
+ void eraseIfImpl(C& c, const P& p, VectorCategory) {
+ c.erase(std::remove_if(c.begin(), c.end(), p), c.end());
+ }
+ }
+
+ 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());
+ }
+
+ template<typename Source, typename Target>
+ void append(Target& target, const Source& source) {
+ target.insert(target.end(), source.begin(), source.end());
+ }
+
+ template<typename Source, typename Target>
+ void assign(Target& target, const Source& source) {
+ target.assign(source.begin(), source.end());
+ }
+
+ template<typename A, typename B, typename C, typename D>
+ B get(const std::map<A, B, C, D>& map, const A& key, const B& defaultValue) {
+ typename std::map<A, B, C, D>::const_iterator i = map.find(key);
+ if (i != map.end()) {
+ return i->second;
+ }
+ else {
+ return defaultValue;
+ }
+ }
+
+ template<typename Container>
+ void safeClear(Container& c) {
+ std::fill(c.begin(), c.end(), 0);
+ c.clear();
+ }
+
+ /*
+ * Functors
+ */
+ template<typename K, typename V>
+ class PairFirstEquals {
+ public:
+ PairFirstEquals(const K& value) : value(value) {
+ }
+
+ bool operator()(const std::pair<K,V>& pair) const {
+ return pair.first == value;
+ }
+
+ private:
+ K value;
+ };
+
+ 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;
+ };
+
+ template <typename Map>
+ bool key_compare(Map const& lhs, Map const& rhs) {
+
+ auto pred = [](decltype(*lhs.begin()) a, decltype(a) b) { return a.first == b.first; };
+
+ return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin(), pred);
+ }
+
+ /**
+ * Ranges
+ */
+ template <typename T>
+ class range_t {
+ public:
+ range_t(T b, T e) : b_(b), e_(e) {}
+
+ T begin() {
+ return b_;
+ }
+ T end() {
+ return e_;
+ }
+ private:
+ T b_;
+ T e_;
+ };
+
+ template <typename T>
+ range_t<T> range(T b, T e) {
+ return range_t<T>(b, e);
+ }
}