File indexing completed on 2024-05-12 15:57:04
0001 /* 0002 * SPDX-FileCopyrightText: 2016 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef KRITA_CONTAINER_UTILS_H 0008 #define KRITA_CONTAINER_UTILS_H 0009 0010 #include <functional> 0011 #include <QList> 0012 0013 namespace KritaUtils 0014 { 0015 0016 template <class T> 0017 bool compareListsUnordered(const QList<T> &a, const QList<T> &b) { 0018 if (a.size() != b.size()) return false; 0019 0020 Q_FOREACH(const T &t, a) { 0021 if (!b.contains(t)) return false; 0022 } 0023 0024 return true; 0025 } 0026 0027 template <class C> 0028 void makeContainerUnique(C &container) { 0029 std::sort(container.begin(), container.end()); 0030 auto newEnd = std::unique(container.begin(), container.end()); 0031 0032 while (newEnd != container.end()) { 0033 newEnd = container.erase(newEnd); 0034 } 0035 } 0036 0037 0038 template <class C, typename KeepIfFunction> 0039 auto filterContainer(C &container, KeepIfFunction keepIf) 0040 -> decltype(bool(keepIf(container[0])), void()) { 0041 0042 auto newEnd = std::remove_if(container.begin(), container.end(), [keepIf] (typename C::reference p) { return !keepIf(p); }); 0043 while (newEnd != container.end()) { 0044 newEnd = container.erase(newEnd); 0045 } 0046 } 0047 0048 template<typename T> 0049 struct is_container 0050 { 0051 typedef typename std::remove_const<T>::type test_type; 0052 0053 template<typename A> 0054 static constexpr bool test( 0055 A *pointer, 0056 A const *const_pointer = nullptr, 0057 decltype(pointer->begin()) * = nullptr, 0058 decltype(pointer->end()) * = nullptr, 0059 decltype(const_pointer->begin()) * = nullptr, 0060 decltype(const_pointer->end()) * = nullptr, 0061 typename A::iterator * it = nullptr, 0062 typename A::const_iterator * constIt = nullptr, 0063 typename A::value_type * = nullptr) { 0064 0065 typedef typename A::iterator iterator; 0066 typedef typename A::const_iterator const_iterator; 0067 typedef typename A::value_type value_type; 0068 return std::is_same<decltype(pointer->begin()),iterator>::value && 0069 std::is_same<decltype(pointer->end()),iterator>::value && 0070 std::is_same<decltype(const_pointer->begin()),const_iterator>::value && 0071 std::is_same<decltype(const_pointer->end()),const_iterator>::value && 0072 std::is_same<decltype(**it),value_type &>::value && 0073 std::is_same<decltype(**constIt),value_type const &>::value; 0074 0075 } 0076 0077 template<typename A> 0078 static constexpr bool test(...) { 0079 return false; 0080 } 0081 0082 static const bool value = test<test_type>(nullptr); 0083 }; 0084 0085 template<typename T> 0086 struct is_appendable_container 0087 { 0088 typedef typename std::remove_const<T>::type test_type; 0089 0090 template<typename A, typename R = decltype(std::declval<A&>().push_back(std::declval<typename A::value_type>()))> 0091 static constexpr bool test(A */*pointer*/) { 0092 return is_container<A>::value && std::is_same<R, void>::value; 0093 } 0094 0095 template<typename A> 0096 static constexpr bool test(...) { 0097 return false; 0098 } 0099 0100 static const bool value = test<test_type>(nullptr); 0101 }; 0102 0103 } 0104 0105 0106 #endif // KRITA_CONTAINER_UTILS_H 0107