1 // Copyright 2016 Google Inc. All rights reserved.
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
16 #include <forward_list>
21 #if defined(ZCPOINTER_TRACK_REFS) && ZCPOINTER_TRACK_REFS
23 template <typename T
> class ref
;
28 class OwnedPtrDeleter
{
33 OwnedPtrDeleter(OwnedPtrDeleter
&& other
) : refs_(std
::move(other
.refs_
)) {
36 void operator()(T
* t
) const {
37 for (auto& ref
: refs_
) {
46 void AddRef(ref
<T
>* ref
) {
47 refs_
.push_front(ref
);
50 void RemoveRef(ref
<T
>* ref
) {
55 std
::forward_list
<ref
<T
>*> refs_
;
58 } // namespace internal
60 using UseAfterFreeException
= std
::logic_error
;
63 class owned
: public std
::unique_ptr
<T
, internal
::OwnedPtrDeleter
<T
>> {
65 using Deleter
= internal
::OwnedPtrDeleter
<T
>;
68 using std
::unique_ptr
<T
, Deleter
>::unique_ptr
;
77 T
* GetRawPointer() const {
83 return this->std
::unique_ptr
<T
, Deleter
>::get();
90 explicit ref(owned
<T
>& o
) : ptr_(o
.GetRawPointer()), deleter_(o
.get_deleter()) {
91 deleter_
.AddRef(this);
94 ref(const ref
<T
>& o
) : ptr_(o
.ptr_
), deleter_(o
.deleter_
), deleted_(o
.deleted_
) {
96 deleter_
.AddRef(this);
100 ref
<T
>& operator=(ref
<T
> o
) {
106 deleter_
.RemoveRef(this);
109 T
* operator->() const {
115 friend class internal
::OwnedPtrDeleter
<T
>;
122 void CheckDeleted() const {
124 throw UseAfterFreeException("attempt to access deleted pointer");
129 internal
::OwnedPtrDeleter
<T
>& deleter_
;
130 bool deleted_
= false;
135 template <typename T
>
136 using owned
= std
::unique_ptr
<T
>;
138 template <typename T
>