| 139 | /// |
| 140 | template <typename T> |
| 141 | struct CefRefCount : public T |
| 142 | { |
| 143 | template <typename U> |
| 144 | CefRefCount(const U *) noexcept : T{}, ref_(1) { |
| 145 | T::base.size = sizeof(U); |
| 146 | T::base.add_ref = _Base_AddRef; |
| 147 | T::base.release = _Base_Release; |
| 148 | T::base.has_one_ref = _Base_HasOneRef; |
| 149 | T::base.has_at_least_one_ref = _Base_HasAtLeastOneRef; |
| 150 | self_delete_ = [](void *self) noexcept { delete static_cast<U *>(self); }; |
| 151 | } |
| 152 | |
| 153 | CefRefCount(nullptr_t) noexcept : CefRefCount(static_cast<T *>(nullptr)) {} |
| 154 | |
| 155 | private: |
| 156 | void(*self_delete_)(void *); |
| 157 | std::atomic<size_t> ref_; |
| 158 | |
| 159 | static void CALLBACK _Base_AddRef(cef_base_ref_counted_t *_) noexcept { |
| 160 | ++reinterpret_cast<CefRefCount *>(_)->ref_; |
| 161 | } |
| 162 | |
| 163 | static int CALLBACK _Base_Release(cef_base_ref_counted_t *_) noexcept { |
| 164 | CefRefCount *self = reinterpret_cast<CefRefCount *>(_); |
| 165 | if (--self->ref_ == 0) { |
| 166 | self->self_delete_(_); |
| 167 | return 1; |
| 168 | } |
| 169 | return 0; |
| 170 | } |
| 171 | |
| 172 | static int CALLBACK _Base_HasOneRef(cef_base_ref_counted_t *_) noexcept { |
| 173 | return reinterpret_cast<CefRefCount *>(_)->ref_ == 1; |
| 174 | } |
| 175 | |
| 176 | static int CALLBACK _Base_HasAtLeastOneRef(cef_base_ref_counted_t *_) noexcept { |
| 177 | return reinterpret_cast<CefRefCount *>(_)->ref_ > 0; |
| 178 | } |
| 179 | }; |
| 180 | |
| 181 | /// cef string interface |
| 182 | struct CefStrBase : cef_string_t |
nothing calls this directly
no outgoing calls
no test coverage detected