/*
- * Copyright 2015 Facebook, Inc.
+ * Copyright 2015-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
class ReadMostlyWeakPtr;
template <typename T, typename RefCount>
class ReadMostlySharedPtr;
+template <typename RefCount>
+class ReadMostlyMainPtrDeleter;
using DefaultRefCount = TLRefCount;
private:
friend class ReadMostlyMainPtr<T, RefCount>;
+ friend class ReadMostlyMainPtrDeleter<RefCount>;
explicit ReadMostlySharedPtrCore(std::shared_ptr<T> ptr) :
ptrRaw_(ptr.get()),
std::shared_ptr<T> ptr_;
};
-}
+} // namespace detail
template <typename T, typename RefCount = DefaultRefCount>
class ReadMostlyMainPtr {
}
}
- std::shared_ptr<T> getStdShared() {
+ std::shared_ptr<T> getStdShared() const {
if (impl_) {
- return impl_->ptr_;
+ return impl_->getShared();
} else {
return {};
}
private:
friend class ReadMostlyWeakPtr<T, RefCount>;
friend class ReadMostlySharedPtr<T, RefCount>;
+ friend class ReadMostlyMainPtrDeleter<RefCount>;
detail::ReadMostlySharedPtrCore<T, RefCount>* impl_{nullptr};
};
std::shared_ptr<T> getStdShared() const {
if (impl_) {
- return impl_->ptr_;
+ return impl_->getShared();
} else {
return {};
}
detail::ReadMostlySharedPtrCore<T, RefCount>* impl_{nullptr};
};
+/**
+ * This can be used to destroy multiple ReadMostlyMainPtrs at once.
+ */
+template <typename RefCount = DefaultRefCount>
+class ReadMostlyMainPtrDeleter {
+ public:
+ ~ReadMostlyMainPtrDeleter() noexcept {
+ RefCount::useGlobal(refCounts_);
+ for (auto& decref : decrefs_) {
+ decref();
+ }
+ }
+
+ template <typename T>
+ void add(ReadMostlyMainPtr<T, RefCount> ptr) noexcept {
+ if (!ptr.impl_) {
+ return;
+ }
+
+ refCounts_.push_back(&ptr.impl_->count_);
+ refCounts_.push_back(&ptr.impl_->weakCount_);
+ decrefs_.push_back([impl = ptr.impl_] { impl->decref(); });
+ ptr.impl_ = nullptr;
+ }
+
+ private:
+ std::vector<RefCount*> refCounts_;
+ std::vector<folly::Function<void()>> decrefs_;
+};
+
+template <typename T, typename RefCount>
+inline bool operator==(
+ const ReadMostlyMainPtr<T, RefCount>& ptr,
+ std::nullptr_t) {
+ return ptr.get() == nullptr;
+}
+
+template <typename T, typename RefCount>
+inline bool operator==(
+ std::nullptr_t,
+ const ReadMostlyMainPtr<T, RefCount>& ptr) {
+ return ptr.get() == nullptr;
+}
+
+template <typename T, typename RefCount>
+inline bool operator==(
+ const ReadMostlySharedPtr<T, RefCount>& ptr,
+ std::nullptr_t) {
+ return ptr.get() == nullptr;
+}
+
+template <typename T, typename RefCount>
+inline bool operator==(
+ std::nullptr_t,
+ const ReadMostlySharedPtr<T, RefCount>& ptr) {
+ return ptr.get() == nullptr;
+}
+
+template <typename T, typename RefCount>
+inline bool operator!=(
+ const ReadMostlyMainPtr<T, RefCount>& ptr,
+ std::nullptr_t) {
+ return !(ptr == nullptr);
+}
+
+template <typename T, typename RefCount>
+inline bool operator!=(
+ std::nullptr_t,
+ const ReadMostlyMainPtr<T, RefCount>& ptr) {
+ return !(ptr == nullptr);
+}
+
+template <typename T, typename RefCount>
+inline bool operator!=(
+ const ReadMostlySharedPtr<T, RefCount>& ptr,
+ std::nullptr_t) {
+ return !(ptr == nullptr);
+}
+
+template <typename T, typename RefCount>
+inline bool operator!=(
+ std::nullptr_t,
+ const ReadMostlySharedPtr<T, RefCount>& ptr) {
+ return !(ptr == nullptr);
}
+} // namespace folly