Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
SharedPtr.h
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2018 ARM Limited 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 #ifndef __SHAREDPTR_H__ 00019 #define __SHAREDPTR_H__ 00020 00021 #include <stdlib.h> 00022 00023 #include <stdint.h> 00024 #include <stddef.h> 00025 00026 #include "platform/mbed_atomic.h" 00027 00028 namespace mbed { 00029 00030 /** Shared pointer class. 00031 * 00032 * A shared pointer is a "smart" pointer that retains ownership of an object using 00033 * reference counting across all smart pointers referencing that object. 00034 * 00035 * @code 00036 * #include "platform/SharedPtr.h" 00037 * 00038 * void test() { 00039 * struct MyStruct { int a; }; 00040 * 00041 * // Create shared pointer 00042 * SharedPtr<MyStruct> ptr( new MyStruct ); 00043 * 00044 * // Increase reference count 00045 * SharedPtr<MyStruct> ptr2( ptr ); 00046 * 00047 * ptr = NULL; // Reference to the struct instance is still held by ptr2 00048 * 00049 * ptr2 = NULL; // The raw pointer is freed 00050 * } 00051 * @endcode 00052 * 00053 * 00054 * It is similar to the std::shared_ptr class introduced in C++11; 00055 * however, this is not a compatible implementation (no weak pointer, no make_shared, no custom deleters and so on.) 00056 * 00057 * Usage: SharedPtr<Class> ptr(new Class()) 00058 * 00059 * When ptr is passed around by value, the copy constructor and 00060 * destructor manages the reference count of the raw pointer. 00061 * If the counter reaches zero, delete is called on the raw pointer. 00062 * 00063 * To avoid loops, use "weak" references by calling the original 00064 * pointer directly through ptr.get(). 00065 */ 00066 00067 template <class T> 00068 class SharedPtr { 00069 public: 00070 /** 00071 * @brief Create empty SharedPtr not pointing to anything. 00072 * @details Used for variable declaration. 00073 */ 00074 SharedPtr(): _ptr(NULL), _counter(NULL) 00075 { 00076 } 00077 00078 /** 00079 * @brief Create empty SharedPtr not pointing to anything. 00080 */ 00081 constexpr SharedPtr(std::nullptr_t) : SharedPtr() 00082 { 00083 } 00084 00085 /** 00086 * @brief Create new SharedPtr 00087 * @param ptr Pointer to take control over 00088 */ 00089 SharedPtr(T *ptr): _ptr(ptr), _counter(NULL) 00090 { 00091 // Allocate counter on the heap, so it can be shared 00092 if (_ptr != NULL) { 00093 _counter = new uint32_t; 00094 *_counter = 1; 00095 } 00096 } 00097 00098 /** 00099 * @brief Destructor. 00100 * @details Decrement reference counter, and delete object if no longer pointed to. 00101 */ 00102 ~SharedPtr() 00103 { 00104 decrement_counter(); 00105 } 00106 00107 /** 00108 * @brief Copy constructor. 00109 * @details Create new SharedPtr from other SharedPtr by 00110 * copying pointer to original object and pointer to counter. 00111 * @param source Object being copied from. 00112 */ 00113 SharedPtr(const SharedPtr &source): _ptr(source._ptr), _counter(source._counter) 00114 { 00115 // Increment reference counter 00116 if (_ptr != NULL) { 00117 core_util_atomic_incr_u32 (_counter, 1); 00118 } 00119 } 00120 00121 /** 00122 * @brief Assignment operator. 00123 * @details Cleanup previous reference and assign new pointer and counter. 00124 * @param source Object being assigned from. 00125 * @return Object being assigned. 00126 */ 00127 SharedPtr operator=(const SharedPtr &source) 00128 { 00129 if (this != &source) { 00130 // Clean up by decrementing counter 00131 decrement_counter(); 00132 00133 // Assign new values 00134 _ptr = source.get(); 00135 _counter = source.get_counter(); 00136 00137 // Increment new counter 00138 if (_ptr != NULL) { 00139 core_util_atomic_incr_u32 (_counter, 1); 00140 } 00141 } 00142 00143 return *this; 00144 } 00145 00146 /** 00147 * @brief Replaces the managed pointer with a new unmanaged pointer. 00148 * @param[in] ptr the new raw pointer to manage. 00149 */ 00150 void reset(T *ptr) 00151 { 00152 // Clean up by decrementing counter 00153 decrement_counter(); 00154 00155 _ptr = ptr; 00156 if (ptr != NULL) { 00157 // Allocate counter on the heap, so it can be shared 00158 _counter = new uint32_t; 00159 *_counter = 1; 00160 } else { 00161 _counter = NULL; 00162 } 00163 } 00164 00165 /** 00166 * @brief Replace the managed pointer with a NULL pointer. 00167 */ 00168 void reset() 00169 { 00170 reset(NULL); 00171 } 00172 00173 /** 00174 * @brief Raw pointer accessor. 00175 * @details Get raw pointer to object pointed to. 00176 * @return Pointer. 00177 */ 00178 T *get() const 00179 { 00180 return _ptr; 00181 } 00182 00183 /** 00184 * @brief Reference count accessor. 00185 * @return Reference count. 00186 */ 00187 uint32_t use_count() const 00188 { 00189 if (_ptr != NULL) { 00190 return core_util_atomic_load_u32 (_counter); 00191 } else { 00192 return 0; 00193 } 00194 } 00195 00196 /** 00197 * @brief Dereference object operator. 00198 * @details Override to return the object pointed to. 00199 */ 00200 T &operator*() const 00201 { 00202 return *_ptr; 00203 } 00204 00205 /** 00206 * @brief Dereference object member operator. 00207 * @details Override to return return member in object pointed to. 00208 */ 00209 T *operator->() const 00210 { 00211 return _ptr; 00212 } 00213 00214 /** 00215 * @brief Boolean conversion operator. 00216 * @return Whether or not the pointer is NULL. 00217 */ 00218 operator bool() const 00219 { 00220 return (_ptr != NULL); 00221 } 00222 00223 private: 00224 /** 00225 * @brief Get pointer to reference counter. 00226 * @return Pointer to reference counter. 00227 */ 00228 uint32_t *get_counter() const 00229 { 00230 return _counter; 00231 } 00232 00233 /** 00234 * @brief Decrement reference counter. 00235 * @details If count reaches zero, free counter and delete object pointed to. 00236 * Does not modify our own pointers - assumption is they will be overwritten 00237 * or destroyed immediately afterwards. 00238 */ 00239 void decrement_counter() 00240 { 00241 if (_ptr != NULL) { 00242 if (core_util_atomic_decr_u32 (_counter, 1) == 0) { 00243 delete _counter; 00244 delete _ptr; 00245 } 00246 } 00247 } 00248 00249 private: 00250 // Pointer to shared object 00251 T *_ptr; 00252 00253 // Pointer to shared reference counter 00254 uint32_t *_counter; 00255 }; 00256 00257 /** Non-member relational operators. 00258 */ 00259 template <class T, class U> 00260 bool operator== (const SharedPtr<T> &lhs, const SharedPtr<U> &rhs) 00261 { 00262 return (lhs.get() == rhs.get()); 00263 } 00264 00265 template <class T, typename U> 00266 bool operator== (const SharedPtr<T> &lhs, U rhs) 00267 { 00268 return (lhs.get() == (T *) rhs); 00269 } 00270 00271 template <class T, typename U> 00272 bool operator== (U lhs, const SharedPtr<T> &rhs) 00273 { 00274 return ((T *) lhs == rhs.get()); 00275 } 00276 00277 /** Non-member relational operators. 00278 */ 00279 template <class T, class U> 00280 bool operator!= (const SharedPtr<T> &lhs, const SharedPtr<U> &rhs) 00281 { 00282 return (lhs.get() != rhs.get()); 00283 } 00284 00285 template <class T, typename U> 00286 bool operator!= (const SharedPtr<T> &lhs, U rhs) 00287 { 00288 return (lhs.get() != (T *) rhs); 00289 } 00290 00291 template <class T, typename U> 00292 bool operator!= (U lhs, const SharedPtr<T> &rhs) 00293 { 00294 return ((T *) lhs != rhs.get()); 00295 } 00296 00297 } /* namespace mbed */ 00298 00299 #ifndef MBED_NO_GLOBAL_USING_DIRECTIVE 00300 using mbed::SharedPtr; 00301 #endif 00302 00303 #endif // __SHAREDPTR_H__
Generated on Tue Jul 12 2022 13:54:50 by
1.7.2