-
Notifications
You must be signed in to change notification settings - Fork 4
/
counted_ptr.h
60 lines (48 loc) · 1.53 KB
/
counted_ptr.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#pragma once
#include <utility>
/**
* counted_ptr holds a pointer to an object of type T.
* When the last counted_ptr for a T is destroyed, its destructor deletes the T.
*/
template<class T>
class counted_ptr {
public:
explicit counted_ptr(T* ptr = nullptr) :ptr_(ptr), use_count_(ptr ? new long(1) : nullptr) {}
~counted_ptr() { decr_count(); }
counted_ptr(const counted_ptr& p) :ptr_(p.ptr_), use_count_(p.use_count_) { incr_count(); }
counted_ptr& operator=(const counted_ptr& p) {
counted_ptr(p).swap(*this);
return *this;
}
counted_ptr(counted_ptr&& p) noexcept :ptr_(p.ptr_), use_count_(p.use_count_) {
p.ptr_ = nullptr;
p.use_count_ = nullptr;
}
counted_ptr& operator=(counted_ptr&& p) noexcept {
counted_ptr(std::move(p)).swap(*this);
return *this;
}
T* get() const { return ptr_; }
T& operator*() const { return *ptr_; }
T* operator->() const { return ptr_; }
explicit operator bool() const { return ptr_ != nullptr; }
long use_count() const { return use_count_ ? *use_count_ : 0; }
void reset(T* ptr = nullptr) { counted_ptr(ptr).swap(*this); }
void swap(counted_ptr& p) {
std::swap(ptr_, p.ptr_);
std::swap(use_count_, p.use_count_);
}
private:
void incr_count() {
if (use_count_)
++*use_count_;
}
void decr_count() {
if (use_count_ && --*use_count_ == 0) {
delete ptr_;
delete use_count_;
}
}
T* ptr_;
long* use_count_;
};