/* * Copyright (c) 2011-2014 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once #include #include #include #include #include namespace Swift { /* * Generic erase() */ namespace Detail { struct VectorCategory {}; struct ListCategory {}; struct MapCategory {}; template struct ContainerTraits; template struct ContainerTraits< std::vector > { typedef VectorCategory Category; }; template<> struct ContainerTraits< std::string > { typedef VectorCategory Category; }; template struct ContainerTraits< std::list > { typedef ListCategory Category; }; template struct ContainerTraits< std::map > { typedef MapCategory Category; }; template void eraseImpl(C& c, const V& v, VectorCategory) { c.erase(std::remove(c.begin(), c.end(), v), c.end()); } template void eraseImpl(C& c, const V& v, ListCategory) { c.remove(v); } template 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 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 void eraseIfImpl(C& c, const P& p, VectorCategory) { c.erase(std::remove_if(c.begin(), c.end(), p), c.end()); } } template void erase(C& container, const V& value) { Detail::eraseImpl(container, value, typename Detail::ContainerTraits::Category()); } template void eraseIf(C& container, const P& predicate) { Detail::eraseIfImpl(container, predicate, typename Detail::ContainerTraits::Category()); } template void append(Target& target, const Source& source) { target.insert(target.end(), source.begin(), source.end()); } template void assign(Target& target, const Source& source) { target.assign(source.begin(), source.end()); } template B get(const std::map& map, const A& key, const B& defaultValue) { typename std::map::const_iterator i = map.find(key); if (i != map.end()) { return i->second; } else { return defaultValue; } } template void safeClear(Container& c) { std::fill(c.begin(), c.end(), 0); c.clear(); } /* * Functors */ template class PairFirstEquals { public: PairFirstEquals(const K& value) : value(value) { } bool operator()(const std::pair& pair) const { return pair.first == value; } private: K value; }; template class PairSecondEquals { public: PairSecondEquals(const V& value) : value(value) { } bool operator()(const std::pair& pair) const { return pair.second == value; } private: V value; }; template 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); } }