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