-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutil.h
143 lines (122 loc) · 3.12 KB
/
util.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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#pragma once
#include "config.h"
namespace co
{
// 鍙浼樺寲鐨刲ock guard
struct fake_lock_guard
{
template <typename Mutex>
explicit fake_lock_guard(Mutex&) {}
};
///////////////////////////////////////
/*
* 杩欓噷鏋勫缓浜嗕竴涓崐渚靛叆寮忕殑寮曠敤璁℃暟浣撶郴, 浣跨敤shared_ptr璇剰鐨勫悓鏃�,
* 鍙堝彲浠ュ皢瀵硅薄鏀惧叆渚靛叆寮忓鍣�, 寰楀埌鏋佷匠鐨勬�ц兘.
*/
// 渚靛叆寮忓紩鐢ㄨ鏁板璞″熀绫�
struct RefObject
{
atomic_t<long> reference_;
RefObject() : reference_{1} {}
virtual ~RefObject() {}
void IncrementRef()
{
++reference_;
}
void DecrementRef()
{
if (--reference_ == 0)
delete this;
}
RefObject(RefObject const&) = delete;
RefObject& operator=(RefObject const&) = delete;
};
// 瑁告寚閽� -> shared_ptr
template <typename T>
typename std::enable_if<std::is_base_of<RefObject, T>::value,
std::shared_ptr<T>>::type
SharedFromThis(T * ptr)
{
ptr->IncrementRef();
return std::shared_ptr<T>(ptr, [](T * self){ self->DecrementRef(); });
}
// make_shared
template <typename T, typename ... Args>
typename std::enable_if<std::is_base_of<RefObject, T>::value,
std::shared_ptr<T>>::type
MakeShared(Args && ... args)
{
T * ptr = new T(std::forward<Args>(args)...);
return std::shared_ptr<T>(ptr, [](T * self){ self->DecrementRef(); });
}
template <typename T>
typename std::enable_if<std::is_base_of<RefObject, T>::value>::type
IncrementRef(T * ptr)
{
ptr->IncrementRef();
}
template <typename T>
typename std::enable_if<!std::is_base_of<RefObject, T>::value>::type
IncrementRef(T * ptr)
{
}
template <typename T>
typename std::enable_if<std::is_base_of<RefObject, T>::value>::type
DecrementRef(T * ptr)
{
ptr->DecrementRef();
}
template <typename T>
typename std::enable_if<!std::is_base_of<RefObject, T>::value>::type
DecrementRef(T * ptr)
{
}
// 寮曠敤璁℃暟guard
class RefGuard
{
public:
template <typename T>
explicit RefGuard(T* ptr) : ptr_(static_cast<RefObject*>(ptr))
{
ptr_->IncrementRef();
}
template <typename T>
explicit RefGuard(T& obj) : ptr_(static_cast<RefObject*>(&obj))
{
ptr_->IncrementRef();
}
~RefGuard()
{
ptr_->DecrementRef();
}
RefGuard(RefGuard const&) = delete;
RefGuard& operator=(RefGuard const&) = delete;
private:
RefObject *ptr_;
};
///////////////////////////////////////
// 鍒涘缓鍗忕▼鐨勬簮鐮佹枃浠朵綅缃�
struct SourceLocation
{
const char* file_ = nullptr;
int lineno_ = 0;
void Init(const char* file, int lineno)
{
file_ = file, lineno_ = lineno;
}
friend bool operator<(SourceLocation const& lhs, SourceLocation const& rhs)
{
if (lhs.file_ != rhs.file_)
return lhs.file_ < rhs.file_;
return lhs.lineno_ < rhs.lineno_;
}
std::string to_string() const
{
std::string s("{file:");
if (file_) s += file_;
s += ", line:";
s += std::to_string(lineno_) + "}";
return s;
}
};
} //namespace co