1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#ifndef _STLPORT_CPP11_EXTENSION_MEMORY_ 18#define _STLPORT_CPP11_EXTENSION_MEMORY_ 19 20// This file extends stlport's <memory> implementation to provide support for: 21// - std::shared_ptr (C++11) 22// - std::unique_ptr (C++11) 23 24// Cloned from master branch vendor/google/native/cmds/sysproxy/shared_ptr.h 25// Upstream commit ff64c352c35c46a14f15503778781889a816eea4 26// Upstream Change-Id: I481ec53b08beecde2bf6dc38e5933342235da3d9 27 28#include <stlport/memory> 29 30namespace std { 31 32template <typename T> 33class shared_ptr { 34 public: 35 shared_ptr(); 36 explicit shared_ptr(T *value); 37 shared_ptr(const shared_ptr &rhs); 38 shared_ptr &operator=(const shared_ptr &rhs); 39 template <typename U> 40 shared_ptr(const shared_ptr<U> &rhs); 41 template <typename U> 42 shared_ptr &operator=(const shared_ptr<U> &rhs); 43 ~shared_ptr(); 44 45 T *get() const; 46 T *operator->() const; 47 T &operator*() const; 48 49 template <typename U> 50 bool operator==(const shared_ptr<U> &rhs) const; 51 template <typename U> 52 bool operator!=(const shared_ptr<U> &rhs) const; 53 template <typename U> 54 bool operator<(const shared_ptr<U> &rhs) const; 55 template <typename U> 56 bool operator<=(const shared_ptr<U> &rhs) const; 57 template <typename U> 58 bool operator>(const shared_ptr<U> &rhs) const; 59 template <typename U> 60 bool operator>=(const shared_ptr<U> &rhs) const; 61 62 void reset(T *value = NULL); 63 64 // TODO(haining) Work with Deleter 65 66 private: 67 template <typename U> 68 friend class shared_ptr; 69 70 struct Node { 71 T *value; 72 int *count; 73 }; 74 // Thread safe decrement, deletes node_ if holding last remaining reference. 75 // Any use of node_ after calling this function is unsafe unless node_ is 76 // reassigned. 77 void DecNode(); 78 79 // Thread safe increment. 80 void IncNode(); 81 82 // Creates a Node referring to NULL. 83 static Node NewNullNode(); 84 85 // Creates a Node referring to value. 86 static Node NewNodeFor(T *value); 87 88 Node node_; 89}; 90 91template <typename T> 92typename shared_ptr<T>::Node shared_ptr<T>::NewNodeFor(T *value) { 93 Node n = {value, new int(1)}; 94 return n; 95} 96 97template <typename T> 98typename shared_ptr<T>::Node shared_ptr<T>::NewNullNode() { 99 return NewNodeFor(NULL); 100} 101 102template <typename T> 103void shared_ptr<T>::reset(T *value) { 104 DecNode(); 105 node_ = NewNodeFor(value); 106} 107 108template <typename T> 109shared_ptr<T>::shared_ptr() : node_(NewNullNode()) {} 110 111template <typename T> 112void shared_ptr<T>::DecNode() { 113 bool should_delete = __atomic_fetch_sub(node_.count, 1, __ATOMIC_SEQ_CST) == 0; 114 // The only accesses to node_ that should be made after this line is the 115 // deletion conditional on should_delete. Anything else is unsafe since 116 // because another thread could have deleted node_ 117 if (should_delete) { 118 delete node_.value; 119 delete node_.count; 120 node_.value = NULL; 121 node_.count = NULL; 122 } 123} 124 125template <typename T> 126void shared_ptr<T>::IncNode() { 127 __atomic_fetch_add(node_.count, 1, __ATOMIC_SEQ_CST); 128} 129 130template <typename T> 131shared_ptr<T>::shared_ptr(T *value) { 132 node_ = NewNodeFor(value); 133} 134 135template <typename T> 136shared_ptr<T>::shared_ptr(const shared_ptr &rhs) : node_(rhs.node_) { 137 IncNode(); 138} 139 140template <typename T> 141template <typename U> 142shared_ptr<T>::shared_ptr(const shared_ptr<U> &rhs) { 143 node_.value = rhs.node_.value; 144 node_.count = rhs.node_.count; 145 node_.m = rhs.node_.m; 146 IncNode(); 147} 148 149template <typename T> 150shared_ptr<T> &shared_ptr<T>::operator=(const shared_ptr &rhs) { 151 if (node_.value == rhs.node_.value) { 152 return *this; 153 } 154 155 DecNode(); 156 node_ = rhs.node_; 157 IncNode(); 158 return *this; 159} 160 161template <typename T> 162template <typename U> 163shared_ptr<T> &shared_ptr<T>::operator=(const shared_ptr<U> &rhs) { 164 if (node_.value == rhs.node_.value) { 165 return *this; 166 } 167 168 DecNode(); 169 node_.value = rhs.node_.value; 170 node_.count = rhs.node_.count; 171 node_.m = rhs.node_.m; 172 IncNode(); 173 return *this; 174} 175 176template <typename T> 177shared_ptr<T>::~shared_ptr() { 178 DecNode(); 179} 180 181template <typename T> 182T *shared_ptr<T>::get() const { 183 return node_.value; 184} 185 186template <typename T> 187T *shared_ptr<T>::operator->() const { 188 return get(); 189} 190 191template <typename T> 192T &shared_ptr<T>::operator*() const { 193 return *node_.value; 194} 195 196template <typename T> 197template <typename U> 198bool shared_ptr<T>::operator==(const shared_ptr<U> &rhs) const { 199 return node_.value == rhs.node_.value; 200} 201 202template <typename T> 203template <typename U> 204bool shared_ptr<T>::operator!=(const shared_ptr<U> &rhs) const { 205 return node_.value != rhs.node_.value; 206} 207 208template <typename T> 209template <typename U> 210bool shared_ptr<T>::operator<(const shared_ptr<U> &rhs) const { 211 return node_.value < rhs.node_.value; 212} 213 214template <typename T> 215template <typename U> 216bool shared_ptr<T>::operator<=(const shared_ptr<U> &rhs) const { 217 return node_.value <= rhs.node_.value; 218} 219 220template <typename T> 221template <typename U> 222bool shared_ptr<T>::operator>(const shared_ptr<U> &rhs) const { 223 return node_.value > rhs.node_.value; 224} 225 226template <typename T> 227template <typename U> 228bool shared_ptr<T>::operator>=(const shared_ptr<U> &rhs) const { 229 return node_.value >= rhs.node_.value; 230} 231 232#if !defined(DISALLOW_COPY_AND_ASSIGN) 233#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ 234 TypeName(const TypeName&); \ 235 void operator=(const TypeName&); 236#endif 237 238#include <cstddef> 239 240// Default deleter for pointer types. 241template <typename T> 242struct DefaultDelete { 243 void operator()(T* p) const { delete p; } 244}; 245 246// Default deleter for array types. 247template <typename T> 248struct DefaultDelete<T[]> { 249 void operator()(T* p) const { delete[] p; } 250}; 251 252// A smart pointer that deletes the given pointer on destruction. 253// Equivalent to C++11's std::unique_ptr 254// Named to be in keeping with Android style but also to avoid 255// collision with any other implementation, until we can switch over 256// to unique_ptr. 257// Use thus: 258// unique_ptr<C> c(new C); 259 260namespace workaround_internal { 261template <typename T, typename Deleter> 262class UniquePtrBase { 263 public: 264 // Construct a new UniquePtrBase, taking ownership of the given raw pointer. 265 explicit UniquePtrBase(T* ptr = 0) : mPtr(ptr), mDeleter() {} 266 explicit UniquePtrBase(T* ptr, Deleter d) : mPtr(ptr), mDeleter(d) {} 267 268 ~UniquePtrBase() { reset(); } 269 270 // Accessors. 271 T* get() const { return mPtr; } 272 273 // Returns the raw pointer and hands over ownership to the caller. 274 // The pointer will not be deleted by UniquePtrBase. 275 T* release() { 276 T* result = mPtr; 277 mPtr = 0; 278 return result; 279 } 280 281 // Takes ownership of the given raw pointer. 282 // If this smart pointer previously owned a different raw pointer, that 283 // raw pointer will be freed. 284 void reset(T* ptr = 0) { 285 T* old_ptr = mPtr; 286 mPtr = ptr; 287 if (old_ptr != NULL && mPtr != old_ptr) { 288 get_deleter()(old_ptr); 289 } 290 } 291 292 Deleter& get_deleter() { return mDeleter; } 293 const Deleter& get_deleter() const { return mDeleter; } 294 295 private: 296 // This is so users can compare against null. Callers should be able 297 // to invoke operator== and operator!= above with NULL pointers but not 298 // with any other pointer. 299 struct RawDummy {}; 300 301 public: 302 bool operator==(const RawDummy*) const { return get() == NULL; } 303 friend bool operator==(const RawDummy*, const UniquePtrBase& self) { 304 return self == NULL; 305 } 306 307 bool operator!=(const RawDummy*) const { return !(*this == NULL); } 308 friend bool operator!=(const RawDummy*, const UniquePtrBase& self) { 309 return self != NULL; 310 } 311 312 private: 313 // The raw pointer. 314 T* mPtr; 315 Deleter mDeleter; 316 317 DISALLOW_COPY_AND_ASSIGN(UniquePtrBase); 318}; 319} // namespace workaround_internal 320 321template <typename T, typename Deleter = DefaultDelete<T> > 322class unique_ptr : public workaround_internal::UniquePtrBase<T, Deleter> { 323 typedef workaround_internal::UniquePtrBase<T, Deleter> Base; 324 public: 325 // Construct a new unique_ptr, taking ownership of the given raw pointer. 326 explicit unique_ptr(T* ptr = 0) : Base(ptr) { } 327 explicit unique_ptr(T* ptr, Deleter d) : Base(ptr, d) { } 328 329 T& operator*() const { return *this->get(); } 330 T* operator->() const { return this->get(); } 331}; 332 333// Partial specialization for array types. Like std::unique_ptr, this removes 334// operator* and operator-> but adds operator[]. 335template <typename T, typename Deleter> 336class unique_ptr<T[], Deleter> : public workaround_internal::UniquePtrBase<T, Deleter> { 337 typedef workaround_internal::UniquePtrBase<T, Deleter> Base; 338 public: 339 explicit unique_ptr(T* ptr = 0) : Base(ptr) { } 340 explicit unique_ptr(T* ptr, Deleter d) : Base(ptr, d) { } 341 342 T& operator[](std::ptrdiff_t i) const { return this->get()[i]; } 343}; 344 345template <typename T> 346shared_ptr<T> make_shared() { 347 return shared_ptr<T>(new T); 348} 349 350} // namespace std 351 352#endif // _STLPORT_CPP11_EXTENSION_MEMORY_ 353