• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright 2021 Huawei Technologies Co., Ltd
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 MINDSPORE_CORE_MINDAPI_BASE_SHARED_PTR_H_
18 #define MINDSPORE_CORE_MINDAPI_BASE_SHARED_PTR_H_
19 
20 #include <cstdint>
21 #include <memory>
22 #include <utility>
23 #include <ostream>
24 #include <functional>
25 
26 namespace mindspore::api {
27 /// \brief SharedPtr wraps a std::shared_ptr and provides wrapper functions according the underlying implementation.
28 template <typename T>
29 class SharedPtr {
30  public:
31   using element_type = T;
32   constexpr SharedPtr() noexcept = default;
SharedPtr(std::nullptr_t)33   constexpr SharedPtr(std::nullptr_t) noexcept : SharedPtr() {}  // NOLINT
34   template <typename U>
SharedPtr(std::shared_ptr<U> && ptr)35   explicit SharedPtr(std::shared_ptr<U> &&ptr) : ptr_(std::move(ptr)) {}
36   template <typename U>
SharedPtr(const SharedPtr<U> & other)37   SharedPtr(const SharedPtr<U> &other) : ptr_(other.ptr_) {}
38   template <typename U>
SharedPtr(SharedPtr<U> && other)39   SharedPtr(SharedPtr<U> &&other) : ptr_(std::move(other.ptr_)) {}
40   template <typename U>
41   SharedPtr &operator=(const SharedPtr<U> &other) {
42     ptr_ = other.ptr_;
43     return *this;
44   }
45   template <typename U>
46   SharedPtr &operator=(SharedPtr<U> &&other) {
47     ptr_ = std::move(other.ptr_);
48     return *this;
49   }
50   ~SharedPtr() = default;
51 
addr()52   std::uintptr_t addr() const { return (ptr_ == nullptr) ? 0 : reinterpret_cast<std::uintptr_t>(ptr_->impl().get()); }
53   element_type &operator*() const noexcept { return *ptr_; }
54   element_type *operator->() const noexcept { return ptr_.get(); }
get()55   element_type *get() const noexcept { return ptr_.get(); }
56   explicit operator bool() const { return addr() != 0; }
57 
58  private:
59   template <typename U>
60   friend class SharedPtr;
61   std::shared_ptr<element_type> ptr_;
62 };
63 
64 template <typename T, typename U>
65 inline bool operator==(const SharedPtr<T> &a, const SharedPtr<U> &b) noexcept {
66   return a.addr() == b.addr();
67 }
68 
69 template <typename T>
70 inline bool operator==(const SharedPtr<T> &a, std::nullptr_t) noexcept {
71   return a.addr() == 0;
72 }
73 
74 template <typename T>
75 inline bool operator==(std::nullptr_t, const SharedPtr<T> &a) noexcept {
76   return a.addr() == 0;
77 }
78 
79 template <typename T, typename U>
80 inline bool operator!=(const SharedPtr<T> &a, const SharedPtr<U> &b) noexcept {
81   return a.addr() != b.addr();
82 }
83 
84 template <typename T>
85 inline bool operator!=(const SharedPtr<T> &a, std::nullptr_t) noexcept {
86   return a.addr() != 0;
87 }
88 
89 template <typename T>
90 inline bool operator!=(std::nullptr_t, const SharedPtr<T> &a) noexcept {
91   return a.addr() != 0;
92 }
93 
94 template <typename T, typename U>
95 inline bool operator<(const SharedPtr<T> &a, const SharedPtr<U> &b) noexcept {
96   return a.addr() < b.addr();
97 }
98 
99 template <typename T>
100 inline bool operator<(const SharedPtr<T> &a, std::nullptr_t) noexcept {
101   return a.addr() < 0;
102 }
103 
104 template <typename T>
105 inline bool operator<(std::nullptr_t, const SharedPtr<T> &a) noexcept {
106   // 'nullptr < ptr' is false only when ptr is nullptr.
107   return a.addr() != 0;
108 }
109 
110 template <typename T, typename U>
111 inline bool operator>(const SharedPtr<T> &a, const SharedPtr<U> &b) noexcept {
112   return a.addr() > b.addr();
113 }
114 
115 template <typename T>
116 inline bool operator>(const SharedPtr<T> &a, std::nullptr_t) noexcept {
117   return a.addr() > 0;
118 }
119 
120 template <typename T>
121 inline bool operator>(std::nullptr_t, const SharedPtr<T> &) noexcept {
122   // 'nullptr > ptr' is always false.
123   return false;
124 }
125 
126 template <typename T, typename U>
127 inline bool operator<=(const SharedPtr<T> &a, const SharedPtr<U> &b) noexcept {
128   return a.addr() <= b.addr();
129 }
130 
131 template <typename T>
132 inline bool operator<=(const SharedPtr<T> &a, std::nullptr_t) noexcept {
133   return a.addr() <= 0;
134 }
135 
136 template <typename T>
137 inline bool operator<=(std::nullptr_t, const SharedPtr<T> &) noexcept {
138   // 'nullptr <= ptr' is always true.
139   return true;
140 }
141 
142 template <typename T, typename U>
143 inline bool operator>=(const SharedPtr<T> &a, const SharedPtr<U> &b) noexcept {
144   return a.addr() >= b.addr();
145 }
146 
147 template <typename T>
148 inline bool operator>=(const SharedPtr<T> &a, std::nullptr_t) noexcept {
149   return a.addr() >= 0;
150 }
151 
152 template <typename T>
153 inline bool operator>=(std::nullptr_t, const SharedPtr<T> &a) noexcept {
154   // 'nullptr >= ptr' is true only when ptr is nullptr.
155   return a.addr() == 0;
156 }
157 
158 template <typename T, typename U, typename V>
159 inline std::basic_ostream<U, V> &operator<<(std::basic_ostream<U, V> &os, const SharedPtr<T> &a) {
160   return (os << reinterpret_cast<void *>(a.addr()));
161 }
162 
163 /// \brief Constructs an object of type T and wraps it in a SharedPtr.
164 ///
165 /// \param[in] args The parameter list for the constructor of T.
166 template <typename T, typename... Args>
MakeShared(Args &&...args)167 inline SharedPtr<T> MakeShared(Args &&... args) {
168   auto ptr = std::make_shared<T>(std::forward<Args>(args)...);
169   return SharedPtr<T>(std::move(ptr));
170 }
171 }  // namespace mindspore::api
172 
173 namespace std {
174 template <typename T>
175 struct hash<mindspore::api::SharedPtr<T>> {
176   size_t operator()(const mindspore::api::SharedPtr<T> &ptr) const noexcept { return static_cast<size_t>(ptr.addr()); }
177 };
178 }  // namespace std
179 
180 #endif  // MINDSPORE_CORE_MINDAPI_BASE_SHARED_PTR_H_
181