mbed library sources. Supersedes mbed-src.
Dependents: Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more
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_critical.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 new SharedPtr 00080 * @param ptr Pointer to take control over 00081 */ 00082 SharedPtr(T *ptr): _ptr(ptr), _counter(NULL) 00083 { 00084 // Allocate counter on the heap, so it can be shared 00085 if (_ptr != NULL) { 00086 _counter = new uint32_t; 00087 *_counter = 1; 00088 } 00089 } 00090 00091 /** 00092 * @brief Destructor. 00093 * @details Decrement reference counter, and delete object if no longer pointed to. 00094 */ 00095 ~SharedPtr() 00096 { 00097 decrement_counter(); 00098 } 00099 00100 /** 00101 * @brief Copy constructor. 00102 * @details Create new SharedPtr from other SharedPtr by 00103 * copying pointer to original object and pointer to counter. 00104 * @param source Object being copied from. 00105 */ 00106 SharedPtr(const SharedPtr &source): _ptr(source._ptr), _counter(source._counter) 00107 { 00108 // Increment reference counter 00109 if (_ptr != NULL) { 00110 core_util_atomic_incr_u32(_counter, 1); 00111 } 00112 } 00113 00114 /** 00115 * @brief Assignment operator. 00116 * @details Cleanup previous reference and assign new pointer and counter. 00117 * @param source Object being assigned from. 00118 * @return Object being assigned. 00119 */ 00120 SharedPtr operator=(const SharedPtr &source) 00121 { 00122 if (this != &source) { 00123 // Clean up by decrementing counter 00124 decrement_counter(); 00125 00126 // Assign new values 00127 _ptr = source.get(); 00128 _counter = source.get_counter(); 00129 00130 // Increment new counter 00131 if (_ptr != NULL) { 00132 core_util_atomic_incr_u32(_counter, 1); 00133 } 00134 } 00135 00136 return *this; 00137 } 00138 00139 /** 00140 * @brief Replaces the managed pointer with a new unmanaged pointer. 00141 * @param[in] ptr the new raw pointer to manage. 00142 */ 00143 void reset(T *ptr) 00144 { 00145 // Clean up by decrementing counter 00146 decrement_counter(); 00147 00148 _ptr = ptr; 00149 if (ptr != NULL) { 00150 // Allocate counter on the heap, so it can be shared 00151 _counter = new uint32_t; 00152 *_counter = 1; 00153 } else { 00154 _counter = NULL; 00155 } 00156 } 00157 00158 /** 00159 * @brief Replace the managed pointer with a NULL pointer. 00160 */ 00161 void reset() 00162 { 00163 reset(NULL); 00164 } 00165 00166 /** 00167 * @brief Raw pointer accessor. 00168 * @details Get raw pointer to object pointed to. 00169 * @return Pointer. 00170 */ 00171 T *get() const 00172 { 00173 return _ptr; 00174 } 00175 00176 /** 00177 * @brief Reference count accessor. 00178 * @return Reference count. 00179 */ 00180 uint32_t use_count() const 00181 { 00182 if (_ptr != NULL) { 00183 core_util_critical_section_enter(); 00184 uint32_t current_counter = *_counter; 00185 core_util_critical_section_exit(); 00186 return current_counter; 00187 } else { 00188 return 0; 00189 } 00190 } 00191 00192 /** 00193 * @brief Dereference object operator. 00194 * @details Override to return the object pointed to. 00195 */ 00196 T &operator*() const 00197 { 00198 return *_ptr; 00199 } 00200 00201 /** 00202 * @brief Dereference object member operator. 00203 * @details Override to return return member in object pointed to. 00204 */ 00205 T *operator->() const 00206 { 00207 return _ptr; 00208 } 00209 00210 /** 00211 * @brief Boolean conversion operator. 00212 * @return Whether or not the pointer is NULL. 00213 */ 00214 operator bool() const 00215 { 00216 return (_ptr != NULL); 00217 } 00218 00219 private: 00220 /** 00221 * @brief Get pointer to reference counter. 00222 * @return Pointer to reference counter. 00223 */ 00224 uint32_t *get_counter() const 00225 { 00226 return _counter; 00227 } 00228 00229 /** 00230 * @brief Decrement reference counter. 00231 * @details If count reaches zero, free counter and delete object pointed to. 00232 * Does not modify our own pointers - assumption is they will be overwritten 00233 * or destroyed immediately afterwards. 00234 */ 00235 void decrement_counter() 00236 { 00237 if (_ptr != NULL) { 00238 uint32_t new_value = core_util_atomic_decr_u32(_counter, 1); 00239 if (new_value == 0) { 00240 delete _counter; 00241 delete _ptr; 00242 } 00243 } 00244 } 00245 00246 private: 00247 // Pointer to shared object 00248 T *_ptr; 00249 00250 // Pointer to shared reference counter 00251 uint32_t *_counter; 00252 }; 00253 00254 /** Non-member relational operators. 00255 */ 00256 template <class T, class U> 00257 bool operator== (const SharedPtr<T> &lhs, const SharedPtr<U> &rhs) 00258 { 00259 return (lhs.get() == rhs.get()); 00260 } 00261 00262 template <class T, typename U> 00263 bool operator== (const SharedPtr<T> &lhs, U rhs) 00264 { 00265 return (lhs.get() == (T *) rhs); 00266 } 00267 00268 template <class T, typename U> 00269 bool operator== (U lhs, const SharedPtr<T> &rhs) 00270 { 00271 return ((T *) lhs == rhs.get()); 00272 } 00273 00274 /** Non-member relational operators. 00275 */ 00276 template <class T, class U> 00277 bool operator!= (const SharedPtr<T> &lhs, const SharedPtr<U> &rhs) 00278 { 00279 return (lhs.get() != rhs.get()); 00280 } 00281 00282 template <class T, typename U> 00283 bool operator!= (const SharedPtr<T> &lhs, U rhs) 00284 { 00285 return (lhs.get() != (T *) rhs); 00286 } 00287 00288 template <class T, typename U> 00289 bool operator!= (U lhs, const SharedPtr<T> &rhs) 00290 { 00291 return ((T *) lhs != rhs.get()); 00292 } 00293 00294 } /* namespace mbed */ 00295 00296 #ifndef MBED_NO_GLOBAL_USING_DIRECTIVE 00297 using mbed::SharedPtr; 00298 #endif 00299 00300 #endif // __SHAREDPTR_H__
Generated on Tue Jul 12 2022 20:41:15 by 1.7.2