Warning, file /include/podio/utilities/MaybeSharedPtr.h was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 #ifndef PODIO_UTILITIES_MAYBESHAREDPTR_H
0002 #define PODIO_UTILITIES_MAYBESHAREDPTR_H
0003
0004 #include <atomic>
0005
0006 namespace podio::utils {
0007
0008 namespace detail {
0009
0010
0011
0012 struct MarkOwnedTag {};
0013 }
0014
0015 constexpr static auto MarkOwned [[maybe_unused]] = detail::MarkOwnedTag{};
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 template <typename T>
0029 class MaybeSharedPtr {
0030 public:
0031
0032 MaybeSharedPtr() = delete;
0033
0034
0035
0036 explicit MaybeSharedPtr(T* p) : m_ptr(p) {
0037 }
0038
0039
0040 explicit MaybeSharedPtr(T* p, detail::MarkOwnedTag) : m_ptr(p), m_ctrlBlock(new ControlBlock()) {
0041 }
0042
0043
0044 MaybeSharedPtr(const MaybeSharedPtr& other) : m_ptr(other.m_ptr), m_ctrlBlock(other.m_ctrlBlock) {
0045
0046 m_ctrlBlock && m_ctrlBlock->count++;
0047 }
0048
0049
0050 MaybeSharedPtr& operator=(MaybeSharedPtr other) {
0051 swap(*this, other);
0052 return *this;
0053 }
0054
0055
0056 MaybeSharedPtr(MaybeSharedPtr&& other) : m_ptr(other.m_ptr), m_ctrlBlock(other.m_ctrlBlock) {
0057 other.m_ptr = nullptr;
0058 other.m_ctrlBlock = nullptr;
0059 }
0060
0061
0062 ~MaybeSharedPtr() {
0063
0064
0065 if (m_ctrlBlock && --m_ctrlBlock->count == 0) {
0066
0067
0068
0069 if (m_ctrlBlock->owned) {
0070 delete m_ptr;
0071 }
0072 delete m_ctrlBlock;
0073 }
0074 }
0075
0076
0077
0078 T* get() const {
0079 return m_ptr;
0080 }
0081
0082
0083 T* release() {
0084 if (m_ctrlBlock) {
0085
0086 m_ctrlBlock->owned = false;
0087 }
0088 return m_ptr;
0089 }
0090
0091 operator bool() const {
0092 return m_ptr;
0093 }
0094
0095 T* operator->() {
0096 return m_ptr;
0097 }
0098 const T* operator->() const {
0099 return m_ptr;
0100 }
0101
0102 T& operator*() {
0103 return *m_ptr;
0104 }
0105 const T& operator*() const {
0106 return *m_ptr;
0107 }
0108
0109 template <typename U>
0110 friend void swap(MaybeSharedPtr<U>& a, MaybeSharedPtr<U>& b);
0111
0112
0113
0114 #define DECLARE_COMPARISON_OPERATOR(op) \
0115 template <typename U> \
0116 friend bool operator op(const MaybeSharedPtr<U>& lhs, const MaybeSharedPtr<U>& rhs); \
0117 template <typename U> \
0118 friend bool operator op(const MaybeSharedPtr<U>& lhs, const U* rhs); \
0119 template <typename U> \
0120 friend bool operator op(const U* lhs, const MaybeSharedPtr<U>& rhs);
0121
0122 DECLARE_COMPARISON_OPERATOR(==)
0123 DECLARE_COMPARISON_OPERATOR(!=)
0124 DECLARE_COMPARISON_OPERATOR(<)
0125 #undef DECLARE_COMPARISON_OPERATOR
0126
0127 private:
0128
0129
0130
0131
0132
0133 struct ControlBlock {
0134 std::atomic<unsigned> count{1};
0135 std::atomic<bool> owned{true};
0136 };
0137
0138 T* m_ptr{nullptr};
0139 ControlBlock* m_ctrlBlock{nullptr};
0140 };
0141
0142 template <typename T>
0143 void swap(MaybeSharedPtr<T>& a, MaybeSharedPtr<T>& b) {
0144 using std::swap;
0145 swap(a.m_ptr, b.m_ptr);
0146 swap(a.m_ctrlBlock, b.m_ctrlBlock);
0147 }
0148
0149
0150 #define DEFINE_COMPARISON_OPERATOR(op) \
0151 template <typename U> \
0152 bool operator op(const MaybeSharedPtr<U>& lhs, const MaybeSharedPtr<U>& rhs) { \
0153 return lhs.m_ptr op rhs.m_ptr; \
0154 }
0155
0156 DEFINE_COMPARISON_OPERATOR(==)
0157 DEFINE_COMPARISON_OPERATOR(!=)
0158 DEFINE_COMPARISON_OPERATOR(<)
0159 #undef DEFINE_COMPARISON_OPERATOR
0160
0161 }
0162
0163 #endif