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