File indexing completed on 2024-05-12 15:43:33
0001 /* 0002 * This file is part of the KDE libraries 0003 * Copyright (C) 2004 Apple Computer, Inc. 0004 * 0005 * This library is free software; you can redistribute it and/or 0006 * modify it under the terms of the GNU Library General Public 0007 * License as published by the Free Software Foundation; either 0008 * version 2 of the License, or (at your option) any later version. 0009 * 0010 * This library is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 * Library General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU Library General Public License 0016 * along with this library; see the file COPYING.LIB. If not, write to 0017 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 * Boston, MA 02110-1301, USA. 0019 * 0020 */ 0021 0022 #ifndef _KJS_PROTECT_H_ 0023 #define _KJS_PROTECT_H_ 0024 0025 #include "value.h" 0026 #include "collector.h" 0027 #include "JSLock.h" 0028 0029 namespace KJS 0030 { 0031 0032 inline void gcProtect(JSValue *val) 0033 { 0034 Collector::protect(val); 0035 } 0036 0037 inline void gcUnprotect(JSValue *val) 0038 { 0039 Collector::unprotect(val); 0040 } 0041 0042 inline void gcProtectNullTolerant(JSValue *val) 0043 { 0044 if (val) { 0045 gcProtect(val); 0046 } 0047 } 0048 0049 inline void gcUnprotectNullTolerant(JSValue *val) 0050 { 0051 if (val) { 0052 gcUnprotect(val); 0053 } 0054 } 0055 0056 // FIXME: Share more code with RefPtr template? The only differences are the ref/deref operation 0057 // and the implicit conversion to raw pointer 0058 template <class T> class ProtectedPtr 0059 { 0060 public: 0061 ProtectedPtr() : m_ptr(nullptr) { } 0062 ProtectedPtr(T *ptr); 0063 ProtectedPtr(const ProtectedPtr &); 0064 ~ProtectedPtr(); 0065 0066 template <class U> ProtectedPtr(const ProtectedPtr<U> &); 0067 0068 T *get() const 0069 { 0070 return m_ptr; 0071 } 0072 operator T *() const 0073 { 0074 return m_ptr; 0075 } 0076 T *operator->() const 0077 { 0078 return m_ptr; 0079 } 0080 0081 bool operator!() const 0082 { 0083 return m_ptr == NULL; 0084 } 0085 0086 ProtectedPtr &operator=(const ProtectedPtr &); 0087 ProtectedPtr &operator=(T *); 0088 0089 private: 0090 T *m_ptr; 0091 }; 0092 0093 template <class T> ProtectedPtr<T>::ProtectedPtr(T *ptr) 0094 : m_ptr(ptr) 0095 { 0096 if (ptr) { 0097 JSLock lock; 0098 gcProtect(ptr); 0099 } 0100 } 0101 0102 template <class T> ProtectedPtr<T>::ProtectedPtr(const ProtectedPtr &o) 0103 : m_ptr(o.get()) 0104 { 0105 if (T *ptr = m_ptr) { 0106 JSLock lock; 0107 gcProtect(ptr); 0108 } 0109 } 0110 0111 template <class T> ProtectedPtr<T>::~ProtectedPtr() 0112 { 0113 if (T *ptr = m_ptr) { 0114 JSLock lock; 0115 gcUnprotect(ptr); 0116 } 0117 } 0118 0119 template <class T> template <class U> ProtectedPtr<T>::ProtectedPtr(const ProtectedPtr<U> &o) 0120 : m_ptr(o.get()) 0121 { 0122 if (T *ptr = m_ptr) { 0123 JSLock lock; 0124 gcProtect(ptr); 0125 } 0126 } 0127 0128 template <class T> ProtectedPtr<T> &ProtectedPtr<T>::operator=(const ProtectedPtr<T> &o) 0129 { 0130 JSLock lock; 0131 T *optr = o.m_ptr; 0132 gcProtectNullTolerant(optr); 0133 gcUnprotectNullTolerant(m_ptr); 0134 m_ptr = optr; 0135 return *this; 0136 } 0137 0138 template <class T> inline ProtectedPtr<T> &ProtectedPtr<T>::operator=(T *optr) 0139 { 0140 JSLock lock; 0141 gcProtectNullTolerant(optr); 0142 gcUnprotectNullTolerant(m_ptr); 0143 m_ptr = optr; 0144 return *this; 0145 } 0146 0147 template <class T> inline bool operator==(const ProtectedPtr<T> &a, const ProtectedPtr<T> &b) 0148 { 0149 return a.get() == b.get(); 0150 } 0151 template <class T> inline bool operator==(const ProtectedPtr<T> &a, const T *b) 0152 { 0153 return a.get() == b; 0154 } 0155 template <class T> inline bool operator==(const T *a, const ProtectedPtr<T> &b) 0156 { 0157 return a == b.get(); 0158 } 0159 0160 template <class T> inline bool operator!=(const ProtectedPtr<T> &a, const ProtectedPtr<T> &b) 0161 { 0162 return a.get() != b.get(); 0163 } 0164 template <class T> inline bool operator!=(const ProtectedPtr<T> &a, const T *b) 0165 { 0166 return a.get() != b; 0167 } 0168 template <class T> inline bool operator!=(const T *a, const ProtectedPtr<T> &b) 0169 { 0170 return a != b.get(); 0171 } 0172 0173 } // namespace 0174 0175 #endif