Coverage Report

Created: 2026-03-15 06:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/brpc/src/butil/intrusive_ptr.hpp
Line
Count
Source
1
#ifndef BUTIL_INTRUSIVE_PTR_HPP
2
#define BUTIL_INTRUSIVE_PTR_HPP
3
4
//  Copyright (c) 2001, 2002 Peter Dimov
5
//
6
// Distributed under the Boost Software License, Version 1.0. (See
7
// accompanying file LICENSE_1_0.txt or copy at
8
// http://www.boost.org/LICENSE_1_0.txt)
9
//
10
//  See http://www.boost.org/libs/smart_ptr/intrusive_ptr.html for documentation.
11
//
12
//  intrusive_ptr
13
//
14
//  A smart pointer that uses intrusive reference counting.
15
//
16
//  Relies on unqualified calls to
17
//  
18
//      void intrusive_ptr_add_ref(T * p);
19
//      void intrusive_ptr_release(T * p);
20
//
21
//          (p != 0)
22
//
23
//  The object is responsible for destroying itself.
24
25
#include <functional>
26
#include <cstddef>
27
#include <ostream>
28
#include "butil/build_config.h"
29
#include "butil/containers/hash_tables.h"
30
31
namespace butil {
32
33
namespace detail {
34
35
// NOTE: sp_convertible is different from butil::is_convertible
36
// (in butil/type_traits.h) that it converts pointers only. Using
37
// butil::is_convertible results in ctor/dtor issues.
38
template< class Y, class T > struct sp_convertible {
39
    typedef char (&yes) [1];
40
    typedef char (&no)  [2];
41
42
    static yes f( T* );
43
    static no  f( ... );
44
45
    enum _vt { value = sizeof((f)(static_cast<Y*>(0))) == sizeof(yes) };
46
};
47
template< class Y, class T > struct sp_convertible<Y, T[]> {
48
    enum _vt { value = false };
49
};
50
template< class Y, class T > struct sp_convertible<Y[], T[]> {
51
    enum _vt { value = sp_convertible<Y[1], T[1]>::value };
52
};
53
template<class Y, std::size_t N, class T> struct sp_convertible<Y[N], T[]> {
54
    enum _vt { value = sp_convertible<Y[1], T[1]>::value };
55
};
56
57
struct sp_empty {};
58
template< bool > struct sp_enable_if_convertible_impl;
59
template<> struct sp_enable_if_convertible_impl<true> { typedef sp_empty type; };
60
template<> struct sp_enable_if_convertible_impl<false> {};
61
template< class Y, class T > struct sp_enable_if_convertible
62
    : public sp_enable_if_convertible_impl<sp_convertible<Y, T>::value> {};
63
64
} // namespace detail
65
66
template<class T> class intrusive_ptr {
67
private:
68
    typedef intrusive_ptr this_type;
69
public:
70
    typedef T element_type;
71
0
    intrusive_ptr() BAIDU_NOEXCEPT : px(0) {}
Unexecuted instantiation: butil::intrusive_ptr<brpc::MongoContext>::intrusive_ptr()
Unexecuted instantiation: butil::intrusive_ptr<brpc::SharedLoadBalancer>::intrusive_ptr()
Unexecuted instantiation: butil::intrusive_ptr<brpc::ProgressiveAttachment>::intrusive_ptr()
Unexecuted instantiation: butil::intrusive_ptr<brpc::ReadableProgressiveAttachment>::intrusive_ptr()
Unexecuted instantiation: butil::intrusive_ptr<brpc::CallMapper>::intrusive_ptr()
Unexecuted instantiation: butil::intrusive_ptr<brpc::ResponseMerger>::intrusive_ptr()
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpServerStream>::intrusive_ptr()
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpStreamBase>::intrusive_ptr()
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpClientImpl>::intrusive_ptr()
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpClientStream>::intrusive_ptr()
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpRetryingClientStream>::intrusive_ptr()
Unexecuted instantiation: butil::intrusive_ptr<brpc::SpanDB>::intrusive_ptr()
Unexecuted instantiation: butil::intrusive_ptr<brpc::NamingServiceThread>::intrusive_ptr()
72
73
0
    intrusive_ptr(T * p, bool add_ref = true): px(p) {
74
0
        if(px != 0 && add_ref) intrusive_ptr_add_ref(px);
75
0
    }
Unexecuted instantiation: butil::intrusive_ptr<brpc::ReadableProgressiveAttachment>::intrusive_ptr(brpc::ReadableProgressiveAttachment*, bool)
Unexecuted instantiation: butil::intrusive_ptr<brpc::SharedLoadBalancer>::intrusive_ptr(brpc::SharedLoadBalancer*, bool)
Unexecuted instantiation: butil::intrusive_ptr<brpc::ProgressiveAttachment>::intrusive_ptr(brpc::ProgressiveAttachment*, bool)
Unexecuted instantiation: butil::intrusive_ptr<brpc::MongoContext>::intrusive_ptr(brpc::MongoContext*, bool)
Unexecuted instantiation: butil::intrusive_ptr<brpc::CallMapper>::intrusive_ptr(brpc::CallMapper*, bool)
Unexecuted instantiation: butil::intrusive_ptr<brpc::ResponseMerger>::intrusive_ptr(brpc::ResponseMerger*, bool)
Unexecuted instantiation: butil::intrusive_ptr<brpc::policy::HttpContext>::intrusive_ptr(brpc::policy::HttpContext*, bool)
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpStreamBase>::intrusive_ptr(brpc::RtmpStreamBase*, bool)
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpServerStream>::intrusive_ptr(brpc::RtmpServerStream*, bool)
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpClientStream>::intrusive_ptr(brpc::RtmpClientStream*, bool)
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpClientImpl>::intrusive_ptr(brpc::RtmpClientImpl*, bool)
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpRetryingClientStream>::intrusive_ptr(brpc::RtmpRetryingClientStream*, bool)
Unexecuted instantiation: butil::intrusive_ptr<brpc::SpanDB>::intrusive_ptr(brpc::SpanDB*, bool)
Unexecuted instantiation: butil::intrusive_ptr<brpc::NamingServiceThread>::intrusive_ptr(brpc::NamingServiceThread*, bool)
76
77
    template<class U>
78
    intrusive_ptr(const intrusive_ptr<U>& rhs,
79
                  typename detail::sp_enable_if_convertible<U,T>::type = detail::sp_empty())
80
        : px(rhs.get()) {
81
        if(px != 0) intrusive_ptr_add_ref(px);
82
    }
83
84
0
    intrusive_ptr(const intrusive_ptr& rhs): px(rhs.px) {
85
0
        if(px != 0) intrusive_ptr_add_ref(px);
86
0
    }
Unexecuted instantiation: butil::intrusive_ptr<brpc::ProgressiveAttachment>::intrusive_ptr(butil::intrusive_ptr<brpc::ProgressiveAttachment> const&)
Unexecuted instantiation: butil::intrusive_ptr<brpc::CallMapper>::intrusive_ptr(butil::intrusive_ptr<brpc::CallMapper> const&)
Unexecuted instantiation: butil::intrusive_ptr<brpc::ResponseMerger>::intrusive_ptr(butil::intrusive_ptr<brpc::ResponseMerger> const&)
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpStreamBase>::intrusive_ptr(butil::intrusive_ptr<brpc::RtmpStreamBase> const&)
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpServerStream>::intrusive_ptr(butil::intrusive_ptr<brpc::RtmpServerStream> const&)
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpClientImpl>::intrusive_ptr(butil::intrusive_ptr<brpc::RtmpClientImpl> const&)
Unexecuted instantiation: butil::intrusive_ptr<brpc::SharedLoadBalancer>::intrusive_ptr(butil::intrusive_ptr<brpc::SharedLoadBalancer> const&)
87
88
0
    ~intrusive_ptr() {
89
0
        if(px != 0) intrusive_ptr_release(px);
90
0
    }
Unexecuted instantiation: butil::intrusive_ptr<brpc::MongoContext>::~intrusive_ptr()
Unexecuted instantiation: butil::intrusive_ptr<brpc::SharedLoadBalancer>::~intrusive_ptr()
Unexecuted instantiation: butil::intrusive_ptr<brpc::ProgressiveAttachment>::~intrusive_ptr()
Unexecuted instantiation: butil::intrusive_ptr<brpc::ReadableProgressiveAttachment>::~intrusive_ptr()
Unexecuted instantiation: butil::intrusive_ptr<brpc::ResponseMerger>::~intrusive_ptr()
Unexecuted instantiation: butil::intrusive_ptr<brpc::CallMapper>::~intrusive_ptr()
Unexecuted instantiation: butil::intrusive_ptr<brpc::policy::HttpContext>::~intrusive_ptr()
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpClientStream>::~intrusive_ptr()
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpStreamBase>::~intrusive_ptr()
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpServerStream>::~intrusive_ptr()
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpRetryingClientStream>::~intrusive_ptr()
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpClientImpl>::~intrusive_ptr()
Unexecuted instantiation: butil::intrusive_ptr<brpc::SpanDB>::~intrusive_ptr()
Unexecuted instantiation: butil::intrusive_ptr<brpc::NamingServiceThread>::~intrusive_ptr()
91
92
    template<class U> intrusive_ptr & operator=(const intrusive_ptr<U>& rhs) {
93
        this_type(rhs).swap(*this);
94
        return *this;
95
    }
96
97
// Move support
98
#if defined(BUTIL_CXX11_ENABLED)
99
0
    intrusive_ptr(intrusive_ptr && rhs) BAIDU_NOEXCEPT : px(rhs.px) {
100
0
        rhs.px = 0;
101
0
    }
Unexecuted instantiation: butil::intrusive_ptr<brpc::CallMapper>::intrusive_ptr(butil::intrusive_ptr<brpc::CallMapper>&&)
Unexecuted instantiation: butil::intrusive_ptr<brpc::ResponseMerger>::intrusive_ptr(butil::intrusive_ptr<brpc::ResponseMerger>&&)
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpStreamBase>::intrusive_ptr(butil::intrusive_ptr<brpc::RtmpStreamBase>&&)
102
103
0
    intrusive_ptr & operator=(intrusive_ptr && rhs) BAIDU_NOEXCEPT {
104
0
        this_type(static_cast< intrusive_ptr && >(rhs)).swap(*this);
105
0
        return *this;
106
0
    }
Unexecuted instantiation: butil::intrusive_ptr<brpc::CallMapper>::operator=(butil::intrusive_ptr<brpc::CallMapper>&&)
Unexecuted instantiation: butil::intrusive_ptr<brpc::ResponseMerger>::operator=(butil::intrusive_ptr<brpc::ResponseMerger>&&)
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpStreamBase>::operator=(butil::intrusive_ptr<brpc::RtmpStreamBase>&&)
107
#endif
108
109
0
    intrusive_ptr & operator=(const intrusive_ptr& rhs) {
110
0
        this_type(rhs).swap(*this);
111
0
        return *this;
112
0
    }
Unexecuted instantiation: butil::intrusive_ptr<brpc::CallMapper>::operator=(butil::intrusive_ptr<brpc::CallMapper> const&)
Unexecuted instantiation: butil::intrusive_ptr<brpc::ResponseMerger>::operator=(butil::intrusive_ptr<brpc::ResponseMerger> const&)
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpStreamBase>::operator=(butil::intrusive_ptr<brpc::RtmpStreamBase> const&)
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpClientImpl>::operator=(butil::intrusive_ptr<brpc::RtmpClientImpl> const&)
Unexecuted instantiation: butil::intrusive_ptr<brpc::SharedLoadBalancer>::operator=(butil::intrusive_ptr<brpc::SharedLoadBalancer> const&)
113
114
0
    intrusive_ptr & operator=(T * rhs) {
115
0
        this_type(rhs).swap(*this);
116
0
        return *this;
117
0
    }
Unexecuted instantiation: butil::intrusive_ptr<brpc::MongoContext>::operator=(brpc::MongoContext*)
Unexecuted instantiation: butil::intrusive_ptr<brpc::CallMapper>::operator=(brpc::CallMapper*)
Unexecuted instantiation: butil::intrusive_ptr<brpc::ResponseMerger>::operator=(brpc::ResponseMerger*)
Unexecuted instantiation: butil::intrusive_ptr<brpc::SpanDB>::operator=(brpc::SpanDB*)
118
119
0
    void reset() BAIDU_NOEXCEPT {
120
0
        this_type().swap(*this);
121
0
    }
Unexecuted instantiation: butil::intrusive_ptr<brpc::MongoContext>::reset()
Unexecuted instantiation: butil::intrusive_ptr<brpc::SharedLoadBalancer>::reset()
Unexecuted instantiation: butil::intrusive_ptr<brpc::CallMapper>::reset()
Unexecuted instantiation: butil::intrusive_ptr<brpc::ResponseMerger>::reset()
122
123
0
    void reset(T * rhs) {
124
0
        this_type(rhs).swap(*this);
125
0
    }
Unexecuted instantiation: butil::intrusive_ptr<brpc::ReadableProgressiveAttachment>::reset(brpc::ReadableProgressiveAttachment*)
Unexecuted instantiation: butil::intrusive_ptr<brpc::SharedLoadBalancer>::reset(brpc::SharedLoadBalancer*)
Unexecuted instantiation: butil::intrusive_ptr<brpc::ProgressiveAttachment>::reset(brpc::ProgressiveAttachment*)
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpStreamBase>::reset(brpc::RtmpStreamBase*)
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpClientStream>::reset(brpc::RtmpClientStream*)
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpRetryingClientStream>::reset(brpc::RtmpRetryingClientStream*)
Unexecuted instantiation: butil::intrusive_ptr<brpc::SpanDB>::reset(brpc::SpanDB*)
Unexecuted instantiation: butil::intrusive_ptr<brpc::NamingServiceThread>::reset(brpc::NamingServiceThread*)
126
127
0
    void reset(T * rhs, bool add_ref) {
128
0
        this_type(rhs, add_ref).swap(*this);
129
0
    }
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpServerStream>::reset(brpc::RtmpServerStream*, bool)
Unexecuted instantiation: butil::intrusive_ptr<brpc::NamingServiceThread>::reset(brpc::NamingServiceThread*, bool)
130
131
0
    T * get() const BAIDU_NOEXCEPT {
132
0
        return px;
133
0
    }
Unexecuted instantiation: butil::intrusive_ptr<brpc::ProgressiveAttachment>::get() const
Unexecuted instantiation: butil::intrusive_ptr<brpc::MongoContext>::get() const
Unexecuted instantiation: butil::intrusive_ptr<brpc::ReadableProgressiveAttachment>::get() const
Unexecuted instantiation: butil::intrusive_ptr<brpc::SharedLoadBalancer>::get() const
Unexecuted instantiation: butil::intrusive_ptr<brpc::ResponseMerger>::get() const
Unexecuted instantiation: butil::intrusive_ptr<brpc::CallMapper>::get() const
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpStreamBase>::get() const
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpServerStream>::get() const
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpClientStream>::get() const
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpClientImpl>::get() const
Unexecuted instantiation: butil::intrusive_ptr<brpc::NamingServiceThread>::get() const
134
135
0
    T * detach() BAIDU_NOEXCEPT {
136
0
        T * ret = px;
137
0
        px = 0;
138
0
        return ret;
139
0
    }
Unexecuted instantiation: butil::intrusive_ptr<brpc::policy::HttpContext>::detach()
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpServerStream>::detach()
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpStreamBase>::detach()
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpClientStream>::detach()
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpRetryingClientStream>::detach()
140
141
    T & operator*() const {
142
        return *px;
143
    }
144
145
0
    T * operator->() const {
146
0
        return px;
147
0
    }
Unexecuted instantiation: butil::intrusive_ptr<brpc::ProgressiveAttachment>::operator->() const
Unexecuted instantiation: butil::intrusive_ptr<brpc::ReadableProgressiveAttachment>::operator->() const
Unexecuted instantiation: butil::intrusive_ptr<brpc::SharedLoadBalancer>::operator->() const
Unexecuted instantiation: butil::intrusive_ptr<brpc::ResponseMerger>::operator->() const
Unexecuted instantiation: butil::intrusive_ptr<brpc::CallMapper>::operator->() const
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpStreamBase>::operator->() const
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpServerStream>::operator->() const
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpClientStream>::operator->() const
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpClientImpl>::operator->() const
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpRetryingClientStream>::operator->() const
Unexecuted instantiation: butil::intrusive_ptr<brpc::SpanDB>::operator->() const
Unexecuted instantiation: butil::intrusive_ptr<brpc::NamingServiceThread>::operator->() const
148
149
    // implicit conversion to "bool"
150
#if defined(BUTIL_CXX11_ENABLED)
151
0
    explicit operator bool () const BAIDU_NOEXCEPT {
152
0
        return px != 0;
153
0
    }
Unexecuted instantiation: butil::intrusive_ptr<brpc::ProgressiveAttachment>::operator bool() const
Unexecuted instantiation: butil::intrusive_ptr<brpc::SharedLoadBalancer>::operator bool() const
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpClientImpl>::operator bool() const
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpStreamBase>::operator bool() const
Unexecuted instantiation: butil::intrusive_ptr<brpc::NamingServiceThread>::operator bool() const
154
#elif defined(__CINT__)
155
    operator bool () const BAIDU_NOEXCEPT {
156
        return px != 0;
157
    }
158
#elif (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304))
159
    typedef element_type * (this_type::*unspecified_bool_type)() const;
160
    operator unspecified_bool_type() const BAIDU_NOEXCEPT {
161
        return px == 0? 0: &this_type::get;
162
    }
163
#else
164
    typedef element_type * this_type::*unspecified_bool_type;
165
    operator unspecified_bool_type() const BAIDU_NOEXCEPT {
166
        return px == 0? 0: &this_type::px;
167
    }
168
#endif
169
170
    // operator! is redundant, but some compilers need it
171
0
    bool operator! () const BAIDU_NOEXCEPT {
172
0
        return px == 0;
173
0
    }
174
175
0
    void swap(intrusive_ptr & rhs) BAIDU_NOEXCEPT {
176
0
        T * tmp = px;
177
0
        px = rhs.px;
178
0
        rhs.px = tmp;
179
0
    }
Unexecuted instantiation: butil::intrusive_ptr<brpc::ReadableProgressiveAttachment>::swap(butil::intrusive_ptr<brpc::ReadableProgressiveAttachment>&)
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpClientImpl>::swap(butil::intrusive_ptr<brpc::RtmpClientImpl>&)
Unexecuted instantiation: butil::intrusive_ptr<brpc::MongoContext>::swap(butil::intrusive_ptr<brpc::MongoContext>&)
Unexecuted instantiation: butil::intrusive_ptr<brpc::SharedLoadBalancer>::swap(butil::intrusive_ptr<brpc::SharedLoadBalancer>&)
Unexecuted instantiation: butil::intrusive_ptr<brpc::ProgressiveAttachment>::swap(butil::intrusive_ptr<brpc::ProgressiveAttachment>&)
Unexecuted instantiation: butil::intrusive_ptr<brpc::CallMapper>::swap(butil::intrusive_ptr<brpc::CallMapper>&)
Unexecuted instantiation: butil::intrusive_ptr<brpc::ResponseMerger>::swap(butil::intrusive_ptr<brpc::ResponseMerger>&)
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpStreamBase>::swap(butil::intrusive_ptr<brpc::RtmpStreamBase>&)
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpServerStream>::swap(butil::intrusive_ptr<brpc::RtmpServerStream>&)
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpClientStream>::swap(butil::intrusive_ptr<brpc::RtmpClientStream>&)
Unexecuted instantiation: butil::intrusive_ptr<brpc::RtmpRetryingClientStream>::swap(butil::intrusive_ptr<brpc::RtmpRetryingClientStream>&)
Unexecuted instantiation: butil::intrusive_ptr<brpc::SpanDB>::swap(butil::intrusive_ptr<brpc::SpanDB>&)
Unexecuted instantiation: butil::intrusive_ptr<brpc::NamingServiceThread>::swap(butil::intrusive_ptr<brpc::NamingServiceThread>&)
180
181
private:
182
    T * px;
183
};
184
185
template<class T, class U>
186
inline bool operator==(const intrusive_ptr<T>& a, const intrusive_ptr<U>& b) {
187
    return a.get() == b.get();
188
}
189
190
template<class T, class U>
191
inline bool operator!=(const intrusive_ptr<T>& a, const intrusive_ptr<U>& b) {
192
    return a.get() != b.get();
193
}
194
195
template<class T, class U>
196
inline bool operator==(const intrusive_ptr<T>& a, U * b) {
197
    return a.get() == b;
198
}
199
200
template<class T, class U>
201
inline bool operator!=(const intrusive_ptr<T>& a, U * b) {
202
    return a.get() != b;
203
}
204
205
template<class T, class U>
206
0
inline bool operator==(T * a, const intrusive_ptr<U>& b) {
207
0
    return a == b.get();
208
0
}
209
210
template<class T, class U>
211
0
inline bool operator!=(T * a, const intrusive_ptr<U>& b) {
212
0
    return a != b.get();
213
0
}
214
215
#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
216
// Resolve the ambiguity between our op!= and the one in rel_ops
217
template<class T>
218
inline bool operator!=(const intrusive_ptr<T>& a, const intrusive_ptr<T>& b) {
219
    return a.get() != b.get();
220
}
221
#endif
222
223
#if defined(BUTIL_CXX11_ENABLED)
224
template<class T>
225
0
inline bool operator==(const intrusive_ptr<T>& p, std::nullptr_t) BAIDU_NOEXCEPT {
226
0
    return p.get() == 0;
227
0
}
Unexecuted instantiation: bool butil::operator==<brpc::ReadableProgressiveAttachment>(butil::intrusive_ptr<brpc::ReadableProgressiveAttachment> const&, decltype(nullptr))
Unexecuted instantiation: bool butil::operator==<brpc::ResponseMerger>(butil::intrusive_ptr<brpc::ResponseMerger> const&, decltype(nullptr))
Unexecuted instantiation: bool butil::operator==<brpc::RtmpStreamBase>(butil::intrusive_ptr<brpc::RtmpStreamBase> const&, decltype(nullptr))
Unexecuted instantiation: bool butil::operator==<brpc::RtmpClientImpl>(butil::intrusive_ptr<brpc::RtmpClientImpl> const&, decltype(nullptr))
Unexecuted instantiation: bool butil::operator==<brpc::SharedLoadBalancer>(butil::intrusive_ptr<brpc::SharedLoadBalancer> const&, decltype(nullptr))
228
template<class T>
229
0
inline bool operator==(std::nullptr_t, const intrusive_ptr<T>& p) BAIDU_NOEXCEPT {
230
0
    return p.get() == 0;
231
0
}
232
233
template<class T>
234
0
inline bool operator!=(const intrusive_ptr<T>& p, std::nullptr_t) BAIDU_NOEXCEPT {
235
0
    return p.get() != 0;
236
0
}
Unexecuted instantiation: bool butil::operator!=<brpc::ProgressiveAttachment>(butil::intrusive_ptr<brpc::ProgressiveAttachment> const&, decltype(nullptr))
Unexecuted instantiation: bool butil::operator!=<brpc::ReadableProgressiveAttachment>(butil::intrusive_ptr<brpc::ReadableProgressiveAttachment> const&, decltype(nullptr))
Unexecuted instantiation: bool butil::operator!=<brpc::CallMapper>(butil::intrusive_ptr<brpc::CallMapper> const&, decltype(nullptr))
Unexecuted instantiation: bool butil::operator!=<brpc::RtmpStreamBase>(butil::intrusive_ptr<brpc::RtmpStreamBase> const&, decltype(nullptr))
Unexecuted instantiation: bool butil::operator!=<brpc::RtmpServerStream>(butil::intrusive_ptr<brpc::RtmpServerStream> const&, decltype(nullptr))
Unexecuted instantiation: bool butil::operator!=<brpc::RtmpClientImpl>(butil::intrusive_ptr<brpc::RtmpClientImpl> const&, decltype(nullptr))
Unexecuted instantiation: bool butil::operator!=<brpc::SharedLoadBalancer>(butil::intrusive_ptr<brpc::SharedLoadBalancer> const&, decltype(nullptr))
237
template<class T>
238
0
inline bool operator!=(std::nullptr_t, const intrusive_ptr<T>& p) BAIDU_NOEXCEPT {
239
0
    return p.get() != 0;
240
0
}
241
#endif  // BUTIL_CXX11_ENABLED
242
243
template<class T>
244
inline bool operator<(const intrusive_ptr<T>& a, const intrusive_ptr<T>& b) {
245
    return std::less<T *>()(a.get(), b.get());
246
}
247
248
template<class T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs) {
249
    lhs.swap(rhs);
250
}
251
252
// mem_fn support
253
254
template<class T> T * get_pointer(const intrusive_ptr<T>& p) {
255
    return p.get();
256
}
257
258
template<class T, class U> intrusive_ptr<T> static_pointer_cast(const intrusive_ptr<U>& p) {
259
    return static_cast<T *>(p.get());
260
}
261
262
template<class T, class U> intrusive_ptr<T> const_pointer_cast(const intrusive_ptr<U>& p) {
263
    return const_cast<T *>(p.get());
264
}
265
266
template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast(const intrusive_ptr<U>& p) {
267
    return dynamic_cast<T *>(p.get());
268
}
269
270
template<class Y> std::ostream & operator<< (std::ostream & os, const intrusive_ptr<Y>& p) {
271
    os << p.get();
272
    return os;
273
}
274
275
} // namespace butil
276
277
// hash_value
278
namespace BUTIL_HASH_NAMESPACE {
279
280
#if defined(COMPILER_GCC)
281
template<typename T>
282
struct hash<butil::intrusive_ptr<T> > {
283
    std::size_t operator()(const butil::intrusive_ptr<T>& p) const {
284
        return hash<T*>()(p.get());
285
    }
286
};
287
#elif defined(COMPILER_MSVC)
288
template<typename T>
289
inline size_t hash_value(const butil::intrusive_ptr<T>& sp) {
290
    return hash_value(p.get());
291
}
292
#endif  // COMPILER
293
294
}  // namespace BUTIL_HASH_NAMESPACE
295
296
#endif  // BUTIL_INTRUSIVE_PTR_HPP