Agora C++ API Reference for All Platforms

Loading...
Searching...
No Matches
AgoraRefPtr.h
1
2// Copyright (c) 2019 Agora.io. All rights reserved
3
4// This program is confidential and proprietary to Agora.io.
5// And may not be copied, reproduced, modified, disclosed to others, published
6// or used, in whole or in part, without the express prior written permission
7// of Agora.io.
8
9#pragma once
10
11#include <memory>
12#if !(__cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800))
13#include <cstddef>
14#endif
15#ifndef OPTIONAL_ENUM_CLASS
16#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
17#define OPTIONAL_ENUM_CLASS enum class
18#else
19#define OPTIONAL_ENUM_CLASS enum
20#endif
21#endif
22
23 namespace agora {
24
25OPTIONAL_ENUM_CLASS RefCountReleaseStatus { kDroppedLastRef, kOtherRefsRemained };
26
27// Interfaces where refcounting is part of the public api should
28// inherit this abstract interface. The implementation of these
29// methods is usually provided by the RefCountedObject template class,
30// applied as a leaf in the inheritance tree.
31 class RefCountInterface {
32 public:
33 virtual void AddRef() const = 0;
34 virtual RefCountReleaseStatus Release() const = 0;
35 virtual bool HasOneRef() const = 0;
36
37 // Non-public destructor, because Release() has exclusive responsibility for
38 // destroying the object.
39 protected:
40 virtual ~RefCountInterface() {}
41};
42
43 template <class T>
44 class agora_refptr {
45 public:
46 agora_refptr() : ptr_(NULL) {}
47
48 agora_refptr(T* p) : ptr_(p) {
49 if (ptr_) ptr_->AddRef();
50 }
51
52 template<typename U>
53 agora_refptr(U* p) : ptr_(p) {
54 if (ptr_) ptr_->AddRef();
55 }
56
57 agora_refptr(const agora_refptr<T>& r) : ptr_(r.get()) {
58 if (ptr_) ptr_->AddRef();
59 }
60
61 template <typename U>
62 agora_refptr(const agora_refptr<U>& r) : ptr_(r.get()) {
63 if (ptr_) ptr_->AddRef();
64 }
65
66#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
67 agora_refptr(agora_refptr<T>&& r) : ptr_(r.move()) {}
68
69 template <typename U>
70 agora_refptr(agora_refptr<U>&& r) : ptr_(r.move()) {}
71#endif
72
73 ~agora_refptr() {
74 reset();
75 }
76
77 T* get() const { return ptr_; }
78 operator bool() const { return (ptr_ != NULL); }
79
80 T* operator->() const { return ptr_; }
81 T& operator*() const { return *ptr_; }
82
83 // Returns the (possibly null) raw pointer, and makes the agora_refptr hold a
84 // null pointer, all without touching the reference count of the underlying
85 // pointed-to object. The object is still reference counted, and the caller of
86 // move() is now the proud owner of one reference, so it is responsible for
87 // calling Release() once on the object when no longer using it.
88 T* move() {
89 T* retVal = ptr_;
90 ptr_ = NULL;
91 return retVal;
92 }
93
94 agora_refptr<T>& operator=(T* p) {
95 if (ptr_ == p) return *this;
96
97 if (p) p->AddRef();
98 if (ptr_) ptr_->Release();
99 ptr_ = p;
100 return *this;
101 }
102
103 agora_refptr<T>& operator=(const agora_refptr<T>& r) {
104 return *this = r.get();
105 }
106
107#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
108 agora_refptr<T>& operator=(agora_refptr<T>&& r) {
109 agora_refptr<T>(std::move(r)).swap(*this);
110 return *this;
111 }
112
113 template <typename U>
114 agora_refptr<T>& operator=(agora_refptr<U>&& r) {
115 agora_refptr<T>(std::move(r)).swap(*this);
116 return *this;
117 }
118#endif
119
120 // For working with std::find()
121 bool operator==(const agora_refptr<T>& r) const { return ptr_ == r.ptr_; }
122
123 // For working with std::set
124 bool operator<(const agora_refptr<T>& r) const { return ptr_ < r.ptr_; }
125
126 void swap(T** pp) {
127 T* p = ptr_;
128 ptr_ = *pp;
129 *pp = p;
130 }
131
132 void swap(agora_refptr<T>& r) { swap(&r.ptr_); }
133
134 void reset() {
135 if (ptr_) {
136 ptr_->Release();
137 ptr_ = NULL;
138 }
139 }
140
141 protected:
142 T* ptr_;
143};
144
145} // namespace agora
146
147#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
148 namespace std {
149 template <typename T>
150 struct hash<agora::agora_refptr<T>> {
151 std::size_t operator()(const agora::agora_refptr<T>& k) const {
152 return reinterpret_cast<size_t>(k.get());
153 }
154};
155} // namespace std
156#endif
agora::RefCountInterface
Definition AgoraRefPtr.h:31
agora::RefCountInterface::HasOneRef
virtual bool HasOneRef() const =0
agora::RefCountInterface::AddRef
virtual void AddRef() const =0
agora::RefCountInterface::Release
virtual RefCountReleaseStatus Release() const =0
agora::RefCountInterface::~RefCountInterface
virtual ~RefCountInterface()
Definition AgoraRefPtr.h:40
agora::agora_refptr
Definition AgoraRefPtr.h:44
agora::agora_refptr::reset
void reset()
Definition AgoraRefPtr.h:134
agora::agora_refptr::operator<
bool operator<(const agora_refptr< T > &r) const
Definition AgoraRefPtr.h:124
agora::agora_refptr::get
T * get() const
Definition AgoraRefPtr.h:77
agora::agora_refptr::operator=
agora_refptr< T > & operator=(agora_refptr< U > &&r)
Definition AgoraRefPtr.h:114
agora::agora_refptr::operator==
bool operator==(const agora_refptr< T > &r) const
Definition AgoraRefPtr.h:121
agora::agora_refptr::swap
void swap(agora_refptr< T > &r)
Definition AgoraRefPtr.h:132
agora::agora_refptr::agora_refptr
agora_refptr()
Definition AgoraRefPtr.h:46
agora::agora_refptr::ptr_
T * ptr_
Definition AgoraRefPtr.h:142
agora::agora_refptr::agora_refptr
agora_refptr(agora_refptr< T > &&r)
Definition AgoraRefPtr.h:67
agora::agora_refptr::operator=
agora_refptr< T > & operator=(T *p)
Definition AgoraRefPtr.h:94
agora::agora_refptr::operator=
agora_refptr< T > & operator=(const agora_refptr< T > &r)
Definition AgoraRefPtr.h:103
agora::agora_refptr::operator->
T * operator->() const
Definition AgoraRefPtr.h:80
agora::agora_refptr::agora_refptr
agora_refptr(agora_refptr< U > &&r)
Definition AgoraRefPtr.h:70
agora::agora_refptr::operator*
T & operator*() const
Definition AgoraRefPtr.h:81
agora::agora_refptr::operator=
agora_refptr< T > & operator=(agora_refptr< T > &&r)
Definition AgoraRefPtr.h:108
agora::agora_refptr::agora_refptr
agora_refptr(const agora_refptr< U > &r)
Definition AgoraRefPtr.h:62
agora::agora_refptr::move
T * move()
Definition AgoraRefPtr.h:88
agora::agora_refptr::~agora_refptr
~agora_refptr()
Definition AgoraRefPtr.h:73
agora::agora_refptr::agora_refptr
agora_refptr(T *p)
Definition AgoraRefPtr.h:48
agora::agora_refptr::swap
void swap(T **pp)
Definition AgoraRefPtr.h:126
agora::agora_refptr::agora_refptr
agora_refptr(const agora_refptr< T > &r)
Definition AgoraRefPtr.h:57
agora::agora_refptr::agora_refptr
agora_refptr(U *p)
Definition AgoraRefPtr.h:53
agora
Definition AgoraAtomicOps.h:21
agora::RefCountReleaseStatus
OPTIONAL_ENUM_CLASS RefCountReleaseStatus
Definition AgoraRefPtr.h:25
std
Definition AgoraOptional.h:881
std::hash< agora::agora_refptr< T > >::operator()
std::size_t operator()(const agora::agora_refptr< T > &k) const
Definition AgoraRefPtr.h:151