ATLAS Offline Software
Loading...
Searching...
No Matches
CachedUniquePtr.icc
Go to the documentation of this file.
1// This file's extension implies that it's C, but it's really -*- C++ -*-.
2/*
3 * Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration.
4 */
5// $Id$
6/**
7 * @file CxxUtils/CachedUniquePtr.icc
8 * @author scott snyder <snyder@bnl.gov>
9 * @date Mar, 2019
10 * @brief Cached unique_ptr with atomic update.
11 */
12
13
14namespace CxxUtils {
15
16
17/**
18 * @brief Default constructor. Sets the element to null.
19 */
20template <class T>
21inline
22CachedUniquePtrT<T>::CachedUniquePtrT()
23 : m_ptr (nullptr)
24{
25 //cppcheck-suppress missingReturn; false positive
26}
27
28
29/**
30 * @brief Constructor from an element.
31 */
32template <class T>
33inline
34CachedUniquePtrT<T>::CachedUniquePtrT (std::unique_ptr<T> elt)
35 : m_ptr (elt.release())
36{
37}
38
39
40/**
41 * @brief Move constructor.
42 */
43template <class T>
44inline
45CachedUniquePtrT<T>::CachedUniquePtrT (CachedUniquePtrT&& other) noexcept
46 : m_ptr (other.release().release())
47{
48}
49
50
51/**
52 * @brief Move.
53 */
54template <class T>
55inline
56CachedUniquePtrT<T>&
57CachedUniquePtrT<T>::operator= (CachedUniquePtrT&& other) noexcept
58{
59 if (this != &other) {
60 store (other.release());
61 }
62 return *this;
63}
64
65
66/**
67 * @brief Destructor.
68 */
69template <class T>
70inline
71CachedUniquePtrT<T>::~CachedUniquePtrT()
72{
73 delete m_ptr;
74}
75
76
77/**
78 * @brief Atomically set the element. If already set, then @c elt is discarded.
79 * @param elt The new value for the element.
80 *
81 * If the current value of the element is null, then set it to @c elt.
82 * Otherwise, delete @c elt.
83 * This is done atomically.
84 * Returns the final value of the element.
85 */
86template <class T>
87inline
88T* CachedUniquePtrT<T>::set (std::unique_ptr<T> elt) const
89{
90 // Set the element to ELT if it is currently null.
91 T* ptr = elt.release();
92 T* expected = nullptr;
93 if (!m_ptr.compare_exchange_strong (expected, ptr)) {
94 // Was already set. Delete the new value.
95 delete ptr;
96 ptr = expected;
97 }
98 return ptr;
99}
100
101
102/**
103 * @brief Store a new value to the element.
104 * Not compatible with other concurrent access.
105 */
106template <class T>
107inline
108void CachedUniquePtrT<T>::store (std::unique_ptr<T> elt) noexcept
109{
110 T* old = m_ptr.exchange (elt.release());
111 delete old;
112}
113
114
115/**
116 * @brief Return the current value of the element.
117 */
118template <class T>
119inline
120T*
121CachedUniquePtrT<T>::get() const
122{
123 return m_ptr.load();
124}
125
126
127/**
128 * @brief Dereference the element.
129 */
130template <class T>
131inline
132T&
133CachedUniquePtrT<T>::operator*() const
134{
135 return *get();
136}
137
138
139/**
140 * @brief Dereference the element.
141 */
142template <class T>
143inline
144T*
145CachedUniquePtrT<T>::operator->() const
146{
147 return get();
148}
149
150
151/**
152 * @brief Test if the element is null.
153 */
154template <class T>
155inline
156CachedUniquePtrT<T>::operator bool() const
157{
158 return get() != nullptr;
159}
160
161
162/**
163 * @brief Transfer ownership from the element: return the current value as a
164 * unique_ptr, leaving the element null.
165 */
166template <class T>
167inline
168std::unique_ptr<T>
169CachedUniquePtrT<T>::release() noexcept
170{
171 T* old = m_ptr.exchange (nullptr);
172 return std::unique_ptr<T> (old);
173}
174
175
176} // namespace CxxUtils