|  | /* | 
|  | * Copyright (C) 2016 The Android Open Source Project | 
|  | * | 
|  | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | * you may not use this file except in compliance with the License. | 
|  | * You may obtain a copy of the License at | 
|  | * | 
|  | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | * Unless required by applicable law or agreed to in writing, software | 
|  | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | * See the License for the specific language governing permissions and | 
|  | * limitations under the License. | 
|  | */ | 
|  |  | 
|  | #ifndef _STLPORT_CPP11_EXTENSION_MEMORY_ | 
|  | #define _STLPORT_CPP11_EXTENSION_MEMORY_ | 
|  |  | 
|  | // This file extends stlport's <memory> implementation to provide support for: | 
|  | //  - std::shared_ptr (C++11) | 
|  | //  - std::unique_ptr (C++11) | 
|  |  | 
|  | // Cloned from master branch vendor/google/native/cmds/sysproxy/shared_ptr.h | 
|  | // Upstream commit ff64c352c35c46a14f15503778781889a816eea4 | 
|  | // Upstream Change-Id: I481ec53b08beecde2bf6dc38e5933342235da3d9 | 
|  |  | 
|  | #include <stlport/memory> | 
|  |  | 
|  | namespace std { | 
|  |  | 
|  | template <typename T> | 
|  | class shared_ptr { | 
|  | public: | 
|  | shared_ptr(); | 
|  | explicit shared_ptr(T *value); | 
|  | shared_ptr(const shared_ptr &rhs); | 
|  | shared_ptr &operator=(const shared_ptr &rhs); | 
|  | template <typename U> | 
|  | shared_ptr(const shared_ptr<U> &rhs); | 
|  | template <typename U> | 
|  | shared_ptr &operator=(const shared_ptr<U> &rhs); | 
|  | ~shared_ptr(); | 
|  |  | 
|  | T *get() const; | 
|  | T *operator->() const; | 
|  | T &operator*() const; | 
|  |  | 
|  | template <typename U> | 
|  | bool operator==(const shared_ptr<U> &rhs) const; | 
|  | template <typename U> | 
|  | bool operator!=(const shared_ptr<U> &rhs) const; | 
|  | template <typename U> | 
|  | bool operator<(const shared_ptr<U> &rhs) const; | 
|  | template <typename U> | 
|  | bool operator<=(const shared_ptr<U> &rhs) const; | 
|  | template <typename U> | 
|  | bool operator>(const shared_ptr<U> &rhs) const; | 
|  | template <typename U> | 
|  | bool operator>=(const shared_ptr<U> &rhs) const; | 
|  |  | 
|  | void reset(T *value = NULL); | 
|  |  | 
|  | // TODO(haining) Work with Deleter | 
|  |  | 
|  | private: | 
|  | template <typename U> | 
|  | friend class shared_ptr; | 
|  |  | 
|  | struct Node { | 
|  | T *value; | 
|  | int *count; | 
|  | }; | 
|  | // Thread safe decrement, deletes node_ if holding last remaining reference. | 
|  | // Any use of node_ after calling this function is unsafe unless node_ is | 
|  | // reassigned. | 
|  | void DecNode(); | 
|  |  | 
|  | // Thread safe increment. | 
|  | void IncNode(); | 
|  |  | 
|  | // Creates a Node referring to NULL. | 
|  | static Node NewNullNode(); | 
|  |  | 
|  | // Creates a Node referring to value. | 
|  | static Node NewNodeFor(T *value); | 
|  |  | 
|  | Node node_; | 
|  | }; | 
|  |  | 
|  | template <typename T> | 
|  | typename shared_ptr<T>::Node shared_ptr<T>::NewNodeFor(T *value) { | 
|  | Node n = {value, new int(1)}; | 
|  | return n; | 
|  | } | 
|  |  | 
|  | template <typename T> | 
|  | typename shared_ptr<T>::Node shared_ptr<T>::NewNullNode() { | 
|  | return NewNodeFor(NULL); | 
|  | } | 
|  |  | 
|  | template <typename T> | 
|  | void shared_ptr<T>::reset(T *value) { | 
|  | DecNode(); | 
|  | node_ = NewNodeFor(value); | 
|  | } | 
|  |  | 
|  | template <typename T> | 
|  | shared_ptr<T>::shared_ptr() : node_(NewNullNode()) {} | 
|  |  | 
|  | template <typename T> | 
|  | void shared_ptr<T>::DecNode() { | 
|  | bool should_delete = __atomic_fetch_sub(node_.count, 1, __ATOMIC_SEQ_CST) == 0; | 
|  | // The only accesses to node_ that should be made after this line is the | 
|  | // deletion conditional on should_delete. Anything else is unsafe since | 
|  | // because another thread could have deleted node_ | 
|  | if (should_delete) { | 
|  | delete node_.value; | 
|  | delete node_.count; | 
|  | node_.value = NULL; | 
|  | node_.count = NULL; | 
|  | } | 
|  | } | 
|  |  | 
|  | template <typename T> | 
|  | void shared_ptr<T>::IncNode() { | 
|  | __atomic_fetch_add(node_.count, 1, __ATOMIC_SEQ_CST); | 
|  | } | 
|  |  | 
|  | template <typename T> | 
|  | shared_ptr<T>::shared_ptr(T *value) { | 
|  | node_ = NewNodeFor(value); | 
|  | } | 
|  |  | 
|  | template <typename T> | 
|  | shared_ptr<T>::shared_ptr(const shared_ptr &rhs) : node_(rhs.node_) { | 
|  | IncNode(); | 
|  | } | 
|  |  | 
|  | template <typename T> | 
|  | template <typename U> | 
|  | shared_ptr<T>::shared_ptr(const shared_ptr<U> &rhs) { | 
|  | node_.value = rhs.node_.value; | 
|  | node_.count = rhs.node_.count; | 
|  | node_.m = rhs.node_.m; | 
|  | IncNode(); | 
|  | } | 
|  |  | 
|  | template <typename T> | 
|  | shared_ptr<T> &shared_ptr<T>::operator=(const shared_ptr &rhs) { | 
|  | if (node_.value == rhs.node_.value) { | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | DecNode(); | 
|  | node_ = rhs.node_; | 
|  | IncNode(); | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | template <typename T> | 
|  | template <typename U> | 
|  | shared_ptr<T> &shared_ptr<T>::operator=(const shared_ptr<U> &rhs) { | 
|  | if (node_.value == rhs.node_.value) { | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | DecNode(); | 
|  | node_.value = rhs.node_.value; | 
|  | node_.count = rhs.node_.count; | 
|  | node_.m = rhs.node_.m; | 
|  | IncNode(); | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | template <typename T> | 
|  | shared_ptr<T>::~shared_ptr() { | 
|  | DecNode(); | 
|  | } | 
|  |  | 
|  | template <typename T> | 
|  | T *shared_ptr<T>::get() const { | 
|  | return node_.value; | 
|  | } | 
|  |  | 
|  | template <typename T> | 
|  | T *shared_ptr<T>::operator->() const { | 
|  | return get(); | 
|  | } | 
|  |  | 
|  | template <typename T> | 
|  | T &shared_ptr<T>::operator*() const { | 
|  | return *node_.value; | 
|  | } | 
|  |  | 
|  | template <typename T> | 
|  | template <typename U> | 
|  | bool shared_ptr<T>::operator==(const shared_ptr<U> &rhs) const { | 
|  | return node_.value == rhs.node_.value; | 
|  | } | 
|  |  | 
|  | template <typename T> | 
|  | template <typename U> | 
|  | bool shared_ptr<T>::operator!=(const shared_ptr<U> &rhs) const { | 
|  | return node_.value != rhs.node_.value; | 
|  | } | 
|  |  | 
|  | template <typename T> | 
|  | template <typename U> | 
|  | bool shared_ptr<T>::operator<(const shared_ptr<U> &rhs) const { | 
|  | return node_.value < rhs.node_.value; | 
|  | } | 
|  |  | 
|  | template <typename T> | 
|  | template <typename U> | 
|  | bool shared_ptr<T>::operator<=(const shared_ptr<U> &rhs) const { | 
|  | return node_.value <= rhs.node_.value; | 
|  | } | 
|  |  | 
|  | template <typename T> | 
|  | template <typename U> | 
|  | bool shared_ptr<T>::operator>(const shared_ptr<U> &rhs) const { | 
|  | return node_.value > rhs.node_.value; | 
|  | } | 
|  |  | 
|  | template <typename T> | 
|  | template <typename U> | 
|  | bool shared_ptr<T>::operator>=(const shared_ptr<U> &rhs) const { | 
|  | return node_.value >= rhs.node_.value; | 
|  | } | 
|  |  | 
|  | #if !defined(DISALLOW_COPY_AND_ASSIGN) | 
|  | #define DISALLOW_COPY_AND_ASSIGN(TypeName) \ | 
|  | TypeName(const TypeName&);               \ | 
|  | void operator=(const TypeName&); | 
|  | #endif | 
|  |  | 
|  | #include <cstddef> | 
|  |  | 
|  | // Default deleter for pointer types. | 
|  | template <typename T> | 
|  | struct DefaultDelete { | 
|  | void operator()(T* p) const { delete p; } | 
|  | }; | 
|  |  | 
|  | // Default deleter for array types. | 
|  | template <typename T> | 
|  | struct DefaultDelete<T[]> { | 
|  | void operator()(T* p) const { delete[] p; } | 
|  | }; | 
|  |  | 
|  | // A smart pointer that deletes the given pointer on destruction. | 
|  | // Equivalent to C++11's std::unique_ptr | 
|  | // Named to be in keeping with Android style but also to avoid | 
|  | // collision with any other implementation, until we can switch over | 
|  | // to unique_ptr. | 
|  | // Use thus: | 
|  | //   unique_ptr<C> c(new C); | 
|  |  | 
|  | namespace workaround_internal { | 
|  | template <typename T, typename Deleter> | 
|  | class UniquePtrBase { | 
|  | public: | 
|  | // Construct a new UniquePtrBase, taking ownership of the given raw pointer. | 
|  | explicit UniquePtrBase(T* ptr = 0) : mPtr(ptr), mDeleter() {} | 
|  | explicit UniquePtrBase(T* ptr, Deleter d) : mPtr(ptr), mDeleter(d) {} | 
|  |  | 
|  | ~UniquePtrBase() { reset(); } | 
|  |  | 
|  | // Accessors. | 
|  | T* get() const { return mPtr; } | 
|  |  | 
|  | // Returns the raw pointer and hands over ownership to the caller. | 
|  | // The pointer will not be deleted by UniquePtrBase. | 
|  | T* release() { | 
|  | T* result = mPtr; | 
|  | mPtr = 0; | 
|  | return result; | 
|  | } | 
|  |  | 
|  | // Takes ownership of the given raw pointer. | 
|  | // If this smart pointer previously owned a different raw pointer, that | 
|  | // raw pointer will be freed. | 
|  | void reset(T* ptr = 0) { | 
|  | T* old_ptr = mPtr; | 
|  | mPtr = ptr; | 
|  | if (old_ptr != NULL && mPtr != old_ptr) { | 
|  | get_deleter()(old_ptr); | 
|  | } | 
|  | } | 
|  |  | 
|  | Deleter& get_deleter() { return mDeleter; } | 
|  | const Deleter& get_deleter() const { return mDeleter; } | 
|  |  | 
|  | private: | 
|  | // This is so users can compare against null. Callers should be able | 
|  | // to invoke operator== and operator!= above with NULL pointers but not | 
|  | // with any other pointer. | 
|  | struct RawDummy {}; | 
|  |  | 
|  | public: | 
|  | bool operator==(const RawDummy*) const { return get() == NULL; } | 
|  | friend bool operator==(const RawDummy*, const UniquePtrBase& self) { | 
|  | return self == NULL; | 
|  | } | 
|  |  | 
|  | bool operator!=(const RawDummy*) const { return !(*this == NULL); } | 
|  | friend bool operator!=(const RawDummy*, const UniquePtrBase& self) { | 
|  | return self != NULL; | 
|  | } | 
|  |  | 
|  | private: | 
|  | // The raw pointer. | 
|  | T* mPtr; | 
|  | Deleter mDeleter; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(UniquePtrBase); | 
|  | }; | 
|  | }  // namespace workaround_internal | 
|  |  | 
|  | template <typename T, typename Deleter = DefaultDelete<T> > | 
|  | class unique_ptr : public workaround_internal::UniquePtrBase<T, Deleter> { | 
|  | typedef workaround_internal::UniquePtrBase<T, Deleter> Base; | 
|  | public: | 
|  | // Construct a new unique_ptr, taking ownership of the given raw pointer. | 
|  | explicit unique_ptr(T* ptr = 0) : Base(ptr) { } | 
|  | explicit unique_ptr(T* ptr, Deleter d) : Base(ptr, d) { } | 
|  |  | 
|  | T& operator*() const { return *this->get(); } | 
|  | T* operator->() const { return this->get(); } | 
|  | }; | 
|  |  | 
|  | // Partial specialization for array types. Like std::unique_ptr, this removes | 
|  | // operator* and operator-> but adds operator[]. | 
|  | template <typename T, typename Deleter> | 
|  | class unique_ptr<T[], Deleter> : public workaround_internal::UniquePtrBase<T, Deleter> { | 
|  | typedef workaround_internal::UniquePtrBase<T, Deleter> Base; | 
|  | public: | 
|  | explicit unique_ptr(T* ptr = 0) : Base(ptr) { } | 
|  | explicit unique_ptr(T* ptr, Deleter d) : Base(ptr, d) { } | 
|  |  | 
|  | T& operator[](std::ptrdiff_t i) const { return this->get()[i]; } | 
|  | }; | 
|  |  | 
|  | template <typename T> | 
|  | shared_ptr<T> make_shared() { | 
|  | return shared_ptr<T>(new T); | 
|  | } | 
|  |  | 
|  | }  // namespace std | 
|  |  | 
|  | #endif  // _STLPORT_CPP11_EXTENSION_MEMORY_ |