File indexing completed on 2024-05-12 15:56:58
0001 /* 0002 * SPDX-FileCopyrightText: 2016 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef KIS_POINTER_UTILS_H 0008 #define KIS_POINTER_UTILS_H 0009 0010 #include <QSharedPointer> 0011 0012 /** 0013 * Convert a raw pointer into a shared pointer 0014 */ 0015 template <class T> 0016 inline QSharedPointer<T> toQShared(T* ptr) { 0017 return QSharedPointer<T>(ptr); 0018 } 0019 0020 /** 0021 * Convert a list of raw pointers into a list of shared pointers 0022 */ 0023 template <class A, template <class C> class List> 0024 List<QSharedPointer<A>> listToQShared(const List<A*> list) { 0025 List<QSharedPointer<A>> newList; 0026 Q_FOREACH(A* value, list) { 0027 newList.append(toQShared(value)); 0028 } 0029 return newList; 0030 } 0031 0032 0033 /** 0034 * Convert a list of strong pointers into a list of weak pointers 0035 */ 0036 template <template <class> class Container, class T> 0037 Container<QWeakPointer<T>> listStrongToWeak(const Container<QSharedPointer<T>> &containter) 0038 { 0039 Container<QWeakPointer<T> > result; 0040 Q_FOREACH (QSharedPointer<T> v, containter) { 0041 result << v; 0042 } 0043 return result; 0044 } 0045 0046 /** 0047 * Convert a list of weak pointers into a list of strong pointers 0048 * 0049 * WARNING: By default, uses "all or nothing" rule. If at least one of 0050 * the weak pointers is invalid, returns an *empty* list! 0051 * Even though some other pointer can still be converted 0052 * correctly. 0053 */ 0054 template <template <class> class Container, class T> 0055 Container<QSharedPointer<T> > listWeakToStrong(const Container<QWeakPointer<T>> &containter, 0056 bool allOrNothing = true) 0057 { 0058 Container<QSharedPointer<T> > result; 0059 Q_FOREACH (QWeakPointer<T> v, containter) { 0060 QSharedPointer<T> strong(v); 0061 if (!strong && allOrNothing) { 0062 result.clear(); 0063 return result; 0064 } 0065 0066 if (strong) { 0067 result << strong; 0068 } 0069 } 0070 return result; 0071 } 0072 0073 /** 0074 * Converts a list of objects with type T into a list of objects of type R. 0075 * The conversion is done implicitly, therefore the c-tor of type R should 0076 * support it. The main usage case is conversion of pointers in "descendant- 0077 * to-parent" way. 0078 */ 0079 template <typename R, typename T, template <typename U> class Container> 0080 inline Container<R> implicitCastList(const Container<T> &list) 0081 { 0082 Container<R> result; 0083 0084 Q_FOREACH(const T &item, list) { 0085 result.append(item); 0086 } 0087 return result; 0088 } 0089 0090 0091 template<class T> 0092 class KisWeakSharedPtr; 0093 template<class T> 0094 class KisSharedPtr; 0095 template<class T> 0096 class KisPinnedSharedPtr; 0097 0098 /** 0099 * \fn removeSharedPointer 0100 * 0101 * A template function for converting any kind of a shared pointer into a 0102 * raw pointer. 0103 */ 0104 0105 template <typename T> 0106 T* removeSharedPointer(T* value) 0107 { 0108 return value; 0109 } 0110 0111 template <typename T> 0112 T* removeSharedPointer(KisPinnedSharedPtr<T> value) 0113 { 0114 return value.data(); 0115 } 0116 0117 template <typename T> 0118 T* removeSharedPointer(KisSharedPtr<T> value) 0119 { 0120 return value.data(); 0121 } 0122 0123 template <typename T> 0124 T* removeSharedPointer(QSharedPointer<T> value) 0125 { 0126 return value.data(); 0127 } 0128 0129 0130 template <typename T> 0131 struct KisSharedPointerTraits 0132 { 0133 }; 0134 0135 template <typename T> 0136 struct KisSharedPointerTraits<QSharedPointer<T>> 0137 { 0138 template <typename U> 0139 using SharedPointerType = QSharedPointer<U>; 0140 using ValueType = T; 0141 0142 template <typename D, typename S> 0143 static inline QSharedPointer<D> dynamicCastSP(QSharedPointer<S> src) { 0144 return src.template dynamicCast<D>(); 0145 } 0146 }; 0147 0148 template <typename T> 0149 struct KisSharedPointerTraits<KisSharedPtr<T>> 0150 { 0151 template <typename U> 0152 using SharedPointerType = KisSharedPtr<U>; 0153 using ValueType = T; 0154 0155 template <typename D, typename S> 0156 static inline KisSharedPtr<D> dynamicCastSP(KisSharedPtr<S> src) { 0157 return KisSharedPtr<D>(dynamic_cast<D*>(src.data())); 0158 } 0159 }; 0160 0161 template <typename T> 0162 struct KisSharedPointerTraits<KisPinnedSharedPtr<T>> 0163 { 0164 template <typename U> 0165 using SharedPointerType = KisPinnedSharedPtr<U>; 0166 using ValueType = T; 0167 0168 template <typename D, typename S> 0169 static inline KisPinnedSharedPtr<D> dynamicCastSP(KisPinnedSharedPtr<S> src) { 0170 return KisPinnedSharedPtr<D>(dynamic_cast<D*>(src.data())); 0171 } 0172 }; 0173 0174 #endif // KIS_POINTER_UTILS_H 0175