summaryrefslogtreecommitdiff
path: root/zen/stl_tools.h
diff options
context:
space:
mode:
Diffstat (limited to 'zen/stl_tools.h')
-rwxr-xr-xzen/stl_tools.h488
1 files changed, 244 insertions, 244 deletions
diff --git a/zen/stl_tools.h b/zen/stl_tools.h
index 74a2b360..b03d7533 100755
--- a/zen/stl_tools.h
+++ b/zen/stl_tools.h
@@ -1,244 +1,244 @@
-// *****************************************************************************
-// * This file is part of the FreeFileSync project. It is distributed under *
-// * GNU General Public License: http://www.gnu.org/licenses/gpl-3.0 *
-// * Copyright (C) Zenju (zenju AT freefilesync DOT org) - All Rights Reserved *
-// *****************************************************************************
-
-#ifndef STL_TOOLS_H_84567184321434
-#define STL_TOOLS_H_84567184321434
-
-#include <set>
-#include <map>
-#include <vector>
-#include <memory>
-#include <algorithm>
-#include "type_tools.h"
-#include "build_info.h"
-
-
-//enhancements for <algorithm>
-namespace zen
-{
-//erase selected elements from any container:
-template <class T, class Alloc, class Predicate>
-void erase_if(std::vector<T, Alloc>& v, Predicate p);
-
-template <class T, class LessType, class Alloc, class Predicate>
-void erase_if(std::set<T, LessType, Alloc>& s, Predicate p);
-
-template <class KeyType, class ValueType, class LessType, class Alloc, class Predicate>
-void erase_if(std::map<KeyType, ValueType, LessType, Alloc>& m, Predicate p);
-
-//append STL containers
-template <class T, class Alloc, class C>
-void append(std::vector<T, Alloc>& v, const C& c);
-
-template <class T, class LessType, class Alloc, class C>
-void append(std::set<T, LessType, Alloc>& s, const C& c);
-
-template <class KeyType, class ValueType, class LessType, class Alloc, class C>
-void append(std::map<KeyType, ValueType, LessType, Alloc>& m, const C& c);
-
-template <class M, class K, class V>
-V& map_add_or_update(M& map, const K& key, const V& value); //efficient add or update without "default-constructible" requirement (Effective STL, item 24)
-
-template <class T, class Alloc>
-void removeDuplicates(std::vector<T, Alloc>& v);
-
-//binary search returning an iterator
-template <class ForwardIterator, class T, typename CompLess>
-ForwardIterator binary_search(ForwardIterator first, ForwardIterator last, const T& value, CompLess less);
-
-template <class BidirectionalIterator, class T>
-BidirectionalIterator find_last(BidirectionalIterator first, BidirectionalIterator last, const T& value);
-
-//replacement for std::find_end taking advantage of bidirectional iterators (and giving the algorithm a reasonable name)
-template <class BidirectionalIterator1, class BidirectionalIterator2>
-BidirectionalIterator1 search_last(BidirectionalIterator1 first1, BidirectionalIterator1 last1,
- BidirectionalIterator2 first2, BidirectionalIterator2 last2);
-
-template <class InputIterator1, class InputIterator2>
-bool equal(InputIterator1 first1, InputIterator1 last1,
- InputIterator2 first2, InputIterator2 last2);
-
-template <class ByteIterator> size_t hashBytes (ByteIterator first, ByteIterator last);
-template <class ByteIterator> size_t hashBytesAppend(size_t hashVal, ByteIterator first, ByteIterator last);
-
-
-//support for custom string classes in std::unordered_set/map
-struct StringHash
-{
- template <class String>
- size_t operator()(const String& str) const
- {
- const auto* strFirst = strBegin(str);
- return hashBytes(reinterpret_cast<const char*>(strFirst),
- reinterpret_cast<const char*>(strFirst + strLength(str)));
- }
-};
-
-
-
-
-
-
-//######################## implementation ########################
-
-template <class T, class Alloc, class Predicate> inline
-void erase_if(std::vector<T, Alloc>& v, Predicate p)
-{
- v.erase(std::remove_if(v.begin(), v.end(), p), v.end());
-}
-
-
-namespace impl
-{
-template <class S, class Predicate> inline
-void set_or_map_erase_if(S& s, Predicate p)
-{
- for (auto it = s.begin(); it != s.end();)
- if (p(*it))
- s.erase(it++);
- else
- ++it;
-}
-}
-
-
-template <class T, class LessType, class Alloc, class Predicate> inline
-void erase_if(std::set<T, LessType, Alloc>& s, Predicate p) { impl::set_or_map_erase_if(s, p); } //don't make this any more generic! e.g. must not compile for std::vector!!!
-
-
-template <class KeyType, class ValueType, class LessType, class Alloc, class Predicate> inline
-void erase_if(std::map<KeyType, ValueType, LessType, Alloc>& m, Predicate p) { impl::set_or_map_erase_if(m, p); }
-
-
-template <class T, class Alloc, class C> inline
-void append(std::vector<T, Alloc>& v, const C& c) { v.insert(v.end(), c.begin(), c.end()); }
-
-
-template <class T, class LessType, class Alloc, class C> inline
-void append(std::set<T, LessType, Alloc>& s, const C& c) { s.insert(c.begin(), c.end()); }
-
-
-template <class KeyType, class ValueType, class LessType, class Alloc, class C> inline
-void append(std::map<KeyType, ValueType, LessType, Alloc>& m, const C& c) { m.insert(c.begin(), c.end()); }
-
-
-template <class M, class K, class V> inline
-V& map_add_or_update(M& map, const K& key, const V& value) //efficient add or update without "default-constructible" requirement (Effective STL, item 24)
-{
- auto it = map.lower_bound(key);
- if (it != map.end() && !(map.key_comp()(key, it->first)))
- {
- it->second = value;
- return it->second;
- }
- else
- return map.insert(it, typename M::value_type(key, value))->second;
-}
-
-
-template <class T, class Alloc> inline
-void removeDuplicates(std::vector<T, Alloc>& v)
-{
- std::sort(v.begin(), v.end());
- v.erase(std::unique(v.begin(), v.end()), v.end());
-}
-
-
-template <class ForwardIterator, class T, typename CompLess> inline
-ForwardIterator binary_search(ForwardIterator first, ForwardIterator last, const T& value, CompLess less)
-{
- first = std::lower_bound(first, last, value, less);
- if (first != last && !less(value, *first))
- return first;
- else
- return last;
-}
-
-
-template <class BidirectionalIterator, class T> inline
-BidirectionalIterator find_last(const BidirectionalIterator first, const BidirectionalIterator last, const T& value)
-{
- for (BidirectionalIterator it = last; it != first;) //reverse iteration: 1. check 2. decrement 3. evaluate
- {
- --it; //
-
- if (*it == value)
- return it;
- }
- return last;
-}
-
-
-template <class BidirectionalIterator1, class BidirectionalIterator2> inline
-BidirectionalIterator1 search_last(const BidirectionalIterator1 first1, BidirectionalIterator1 last1,
- const BidirectionalIterator2 first2, const BidirectionalIterator2 last2)
-{
- const BidirectionalIterator1 itNotFound = last1;
-
- //reverse iteration: 1. check 2. decrement 3. evaluate
- for (;;)
- {
- BidirectionalIterator1 it1 = last1;
- BidirectionalIterator2 it2 = last2;
-
- for (;;)
- {
- if (it2 == first2) return it1;
- if (it1 == first1) return itNotFound;
-
- --it1;
- --it2;
-
- if (*it1 != *it2) break;
- }
- --last1;
- }
-}
-
-
-template <class InputIterator1, class InputIterator2> inline
-bool equal(InputIterator1 first1, InputIterator1 last1,
- InputIterator2 first2, InputIterator2 last2)
-{
- return last1 - first1 == last2 - first2 && std::equal(first1, last1, first2);
-}
-
-
-
-
-template <class ByteIterator> inline
-size_t hashBytes(ByteIterator first, ByteIterator last)
-{
- //FNV-1a: http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
-#ifdef ZEN_BUILD_32BIT
- const size_t basis = 2166136261U;
-#elif defined ZEN_BUILD_64BIT
- const size_t basis = 14695981039346656037ULL;
-#endif
- return hashBytesAppend(basis, first, last);
-}
-
-
-template <class ByteIterator> inline
-size_t hashBytesAppend(size_t hashVal, ByteIterator first, ByteIterator last)
-{
-#ifdef ZEN_BUILD_32BIT
- const size_t prime = 16777619U;
-#elif defined ZEN_BUILD_64BIT
- const size_t prime = 1099511628211ULL;
-#endif
- static_assert(sizeof(typename std::iterator_traits<ByteIterator>::value_type) == 1, "");
-
- for (; first != last; ++first)
- {
- hashVal ^= static_cast<size_t>(*first);
- hashVal *= prime;
- }
- return hashVal;
-}
-}
-
-#endif //STL_TOOLS_H_84567184321434
+// *****************************************************************************
+// * This file is part of the FreeFileSync project. It is distributed under *
+// * GNU General Public License: http://www.gnu.org/licenses/gpl-3.0 *
+// * Copyright (C) Zenju (zenju AT freefilesync DOT org) - All Rights Reserved *
+// *****************************************************************************
+
+#ifndef STL_TOOLS_H_84567184321434
+#define STL_TOOLS_H_84567184321434
+
+#include <set>
+#include <map>
+#include <vector>
+#include <memory>
+#include <algorithm>
+#include "type_tools.h"
+#include "build_info.h"
+
+
+//enhancements for <algorithm>
+namespace zen
+{
+//erase selected elements from any container:
+template <class T, class Alloc, class Predicate>
+void erase_if(std::vector<T, Alloc>& v, Predicate p);
+
+template <class T, class LessType, class Alloc, class Predicate>
+void erase_if(std::set<T, LessType, Alloc>& s, Predicate p);
+
+template <class KeyType, class ValueType, class LessType, class Alloc, class Predicate>
+void erase_if(std::map<KeyType, ValueType, LessType, Alloc>& m, Predicate p);
+
+//append STL containers
+template <class T, class Alloc, class C>
+void append(std::vector<T, Alloc>& v, const C& c);
+
+template <class T, class LessType, class Alloc, class C>
+void append(std::set<T, LessType, Alloc>& s, const C& c);
+
+template <class KeyType, class ValueType, class LessType, class Alloc, class C>
+void append(std::map<KeyType, ValueType, LessType, Alloc>& m, const C& c);
+
+template <class M, class K, class V>
+V& map_add_or_update(M& map, const K& key, const V& value); //efficient add or update without "default-constructible" requirement (Effective STL, item 24)
+
+template <class T, class Alloc>
+void removeDuplicates(std::vector<T, Alloc>& v);
+
+//binary search returning an iterator
+template <class ForwardIterator, class T, typename CompLess>
+ForwardIterator binary_search(ForwardIterator first, ForwardIterator last, const T& value, CompLess less);
+
+template <class BidirectionalIterator, class T>
+BidirectionalIterator find_last(BidirectionalIterator first, BidirectionalIterator last, const T& value);
+
+//replacement for std::find_end taking advantage of bidirectional iterators (and giving the algorithm a reasonable name)
+template <class BidirectionalIterator1, class BidirectionalIterator2>
+BidirectionalIterator1 search_last(BidirectionalIterator1 first1, BidirectionalIterator1 last1,
+ BidirectionalIterator2 first2, BidirectionalIterator2 last2);
+
+template <class InputIterator1, class InputIterator2>
+bool equal(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, InputIterator2 last2);
+
+template <class ByteIterator> size_t hashBytes (ByteIterator first, ByteIterator last);
+template <class ByteIterator> size_t hashBytesAppend(size_t hashVal, ByteIterator first, ByteIterator last);
+
+
+//support for custom string classes in std::unordered_set/map
+struct StringHash
+{
+ template <class String>
+ size_t operator()(const String& str) const
+ {
+ const auto* strFirst = strBegin(str);
+ return hashBytes(reinterpret_cast<const char*>(strFirst),
+ reinterpret_cast<const char*>(strFirst + strLength(str)));
+ }
+};
+
+
+
+
+
+
+//######################## implementation ########################
+
+template <class T, class Alloc, class Predicate> inline
+void erase_if(std::vector<T, Alloc>& v, Predicate p)
+{
+ v.erase(std::remove_if(v.begin(), v.end(), p), v.end());
+}
+
+
+namespace impl
+{
+template <class S, class Predicate> inline
+void set_or_map_erase_if(S& s, Predicate p)
+{
+ for (auto it = s.begin(); it != s.end();)
+ if (p(*it))
+ s.erase(it++);
+ else
+ ++it;
+}
+}
+
+
+template <class T, class LessType, class Alloc, class Predicate> inline
+void erase_if(std::set<T, LessType, Alloc>& s, Predicate p) { impl::set_or_map_erase_if(s, p); } //don't make this any more generic! e.g. must not compile for std::vector!!!
+
+
+template <class KeyType, class ValueType, class LessType, class Alloc, class Predicate> inline
+void erase_if(std::map<KeyType, ValueType, LessType, Alloc>& m, Predicate p) { impl::set_or_map_erase_if(m, p); }
+
+
+template <class T, class Alloc, class C> inline
+void append(std::vector<T, Alloc>& v, const C& c) { v.insert(v.end(), c.begin(), c.end()); }
+
+
+template <class T, class LessType, class Alloc, class C> inline
+void append(std::set<T, LessType, Alloc>& s, const C& c) { s.insert(c.begin(), c.end()); }
+
+
+template <class KeyType, class ValueType, class LessType, class Alloc, class C> inline
+void append(std::map<KeyType, ValueType, LessType, Alloc>& m, const C& c) { m.insert(c.begin(), c.end()); }
+
+
+template <class M, class K, class V> inline
+V& map_add_or_update(M& map, const K& key, const V& value) //efficient add or update without "default-constructible" requirement (Effective STL, item 24)
+{
+ auto it = map.lower_bound(key);
+ if (it != map.end() && !(map.key_comp()(key, it->first)))
+ {
+ it->second = value;
+ return it->second;
+ }
+ else
+ return map.insert(it, typename M::value_type(key, value))->second;
+}
+
+
+template <class T, class Alloc> inline
+void removeDuplicates(std::vector<T, Alloc>& v)
+{
+ std::sort(v.begin(), v.end());
+ v.erase(std::unique(v.begin(), v.end()), v.end());
+}
+
+
+template <class ForwardIterator, class T, typename CompLess> inline
+ForwardIterator binary_search(ForwardIterator first, ForwardIterator last, const T& value, CompLess less)
+{
+ first = std::lower_bound(first, last, value, less);
+ if (first != last && !less(value, *first))
+ return first;
+ else
+ return last;
+}
+
+
+template <class BidirectionalIterator, class T> inline
+BidirectionalIterator find_last(const BidirectionalIterator first, const BidirectionalIterator last, const T& value)
+{
+ for (BidirectionalIterator it = last; it != first;) //reverse iteration: 1. check 2. decrement 3. evaluate
+ {
+ --it; //
+
+ if (*it == value)
+ return it;
+ }
+ return last;
+}
+
+
+template <class BidirectionalIterator1, class BidirectionalIterator2> inline
+BidirectionalIterator1 search_last(const BidirectionalIterator1 first1, BidirectionalIterator1 last1,
+ const BidirectionalIterator2 first2, const BidirectionalIterator2 last2)
+{
+ const BidirectionalIterator1 itNotFound = last1;
+
+ //reverse iteration: 1. check 2. decrement 3. evaluate
+ for (;;)
+ {
+ BidirectionalIterator1 it1 = last1;
+ BidirectionalIterator2 it2 = last2;
+
+ for (;;)
+ {
+ if (it2 == first2) return it1;
+ if (it1 == first1) return itNotFound;
+
+ --it1;
+ --it2;
+
+ if (*it1 != *it2) break;
+ }
+ --last1;
+ }
+}
+
+
+template <class InputIterator1, class InputIterator2> inline
+bool equal(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, InputIterator2 last2)
+{
+ return last1 - first1 == last2 - first2 && std::equal(first1, last1, first2);
+}
+
+
+
+
+template <class ByteIterator> inline
+size_t hashBytes(ByteIterator first, ByteIterator last)
+{
+ //FNV-1a: http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
+#ifdef ZEN_BUILD_32BIT
+ const size_t basis = 2166136261U;
+#elif defined ZEN_BUILD_64BIT
+ const size_t basis = 14695981039346656037ULL;
+#endif
+ return hashBytesAppend(basis, first, last);
+}
+
+
+template <class ByteIterator> inline
+size_t hashBytesAppend(size_t hashVal, ByteIterator first, ByteIterator last)
+{
+#ifdef ZEN_BUILD_32BIT
+ const size_t prime = 16777619U;
+#elif defined ZEN_BUILD_64BIT
+ const size_t prime = 1099511628211ULL;
+#endif
+ static_assert(sizeof(typename std::iterator_traits<ByteIterator>::value_type) == 1, "");
+
+ for (; first != last; ++first)
+ {
+ hashVal ^= static_cast<size_t>(*first);
+ hashVal *= prime;
+ }
+ return hashVal;
+}
+}
+
+#endif //STL_TOOLS_H_84567184321434
bgstack15