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-2019 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}
26
27
28/**
29 * @brief Constructor from an element.
30 */
31template <class T>
32inline
33CachedUniquePtrT<T>::CachedUniquePtrT (std::unique_ptr<T> elt)
34 : m_ptr (elt.release())
35{
36}
37
38
39/**
40 * @brief Move constructor.
41 */
42template <class T>
43inline
44CachedUniquePtrT<T>::CachedUniquePtrT (CachedUniquePtrT&& other) noexcept
45 : m_ptr (other.release().release())
46{
47}
48
49
50/**
51 * @brief Move.
52 */
53template <class T>
54inline
55CachedUniquePtrT<T>&
56CachedUniquePtrT<T>::operator= (CachedUniquePtrT&& other) noexcept
57{
58 if (this != &other) {
59 store (other.release());
60 }
61 return *this;
62}
63
64
65/**
66 * @brief Destructor.
67 */
68template <class T>
69inline
70CachedUniquePtrT<T>::~CachedUniquePtrT()
71{
72 delete m_ptr;
73}
74
75
76/**
77 * @brief Atomically set the element. If already set, then @c elt is discarded.
78 * @param elt The new value for the element.
79 *
80 * If the current value of the element is null, then set it to @c elt.
81 * Otherwise, delete @c elt.
82 * This is done atomically.
83 * Returns the final value of the element.
84 */
85template <class T>
86inline
87T* CachedUniquePtrT<T>::set (std::unique_ptr<T> elt) const
88{
89 // Set the element to ELT if it is currently null.
90 T* ptr = elt.release();
91 T* expected = nullptr;
92 if (!m_ptr.compare_exchange_strong (expected, ptr)) {
93 // Was already set. Delete the new value.
94 delete ptr;
95 ptr = expected;
96 }
97 return ptr;
98}
99
100
101/**
102 * @brief Store a new value to the element.
103 * Not compatible with other concurrent access.
104 */
105template <class T>
106inline
107void CachedUniquePtrT<T>::store (std::unique_ptr<T> elt) noexcept
108{
109 T* old = m_ptr.exchange (elt.release());
110 delete old;
111}
112
113
114/**
115 * @brief Return the current value of the element.
116 */
117template <class T>
118inline
119T*
120CachedUniquePtrT<T>::get() const
121{
122 return m_ptr.load();
123}
124
125
126/**
127 * @brief Dereference the element.
128 */
129template <class T>
130inline
131T&
132CachedUniquePtrT<T>::operator*() const
133{
134 return *get();
135}
136
137
138/**
139 * @brief Dereference the element.
140 */
141template <class T>
142inline
143T*
144CachedUniquePtrT<T>::operator->() const
145{
146 return get();
147}
148
149
150/**
151 * @brief Test if the element is null.
152 */
153template <class T>
154inline
155CachedUniquePtrT<T>::operator bool() const
156{
157 return get() != nullptr;
158}
159
160
161/**
162 * @brief Transfer ownership from the element: return the current value as a
163 * unique_ptr, leaving the element null.
164 */
165template <class T>
166inline
167std::unique_ptr<T>
168CachedUniquePtrT<T>::release() noexcept
169{
170 T* old = m_ptr.exchange (nullptr);
171 return std::unique_ptr<T> (old);
172}
173
174
175} // namespace CxxUtils