nss: upgrade to release 3.73
[LibreOffice.git] / include / rtl / ref.hxx
blob838be87c2c895597d8545da34464d43eaa408b17
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_RTL_REF_HXX
21 #define INCLUDED_RTL_REF_HXX
23 #include "sal/config.h"
25 #include <cassert>
26 #include <cstddef>
27 #include <functional>
28 #ifdef LIBO_INTERNAL_ONLY
29 #include <type_traits>
30 #endif
32 #include "sal/types.h"
34 namespace rtl
37 /** Template reference class for reference type.
39 template <class reference_type>
40 class Reference
42 /** The <b>reference_type</b> body pointer.
44 reference_type * m_pBody;
47 public:
48 /** Constructor...
50 Reference()
51 : m_pBody (NULL)
55 /** Constructor...
57 Reference (reference_type * pBody, __sal_NoAcquire)
58 : m_pBody (pBody)
62 /** Constructor...
64 Reference (reference_type * pBody)
65 : m_pBody (pBody)
67 if (m_pBody)
68 m_pBody->acquire();
71 /** Copy constructor...
73 Reference (const Reference<reference_type> & handle)
74 : m_pBody (handle.m_pBody)
76 if (m_pBody)
77 m_pBody->acquire();
80 #ifdef LIBO_INTERNAL_ONLY
81 /** Move constructor...
83 Reference (Reference<reference_type> && handle) noexcept
84 : m_pBody (handle.m_pBody)
86 handle.m_pBody = nullptr;
88 #endif
90 #if defined LIBO_INTERNAL_ONLY
91 /** Up-casting conversion constructor: Copies interface reference.
93 Does not work for up-casts to ambiguous bases.
95 @param rRef another reference
97 template< class derived_type >
98 inline Reference(
99 const Reference< derived_type > & rRef,
100 std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 )
101 : m_pBody (rRef.get())
103 if (m_pBody)
104 m_pBody->acquire();
106 #endif
108 /** Destructor...
110 ~Reference() COVERITY_NOEXCEPT_FALSE
112 if (m_pBody)
113 m_pBody->release();
116 /** Set...
117 Similar to assignment.
119 Reference<reference_type> &
120 SAL_CALL set (reference_type * pBody)
122 if (pBody)
123 pBody->acquire();
124 reference_type * const pOld = m_pBody;
125 m_pBody = pBody;
126 if (pOld)
127 pOld->release();
128 return *this;
131 /** Assignment.
132 Unbinds this instance from its body (if bound) and
133 bind it to the body represented by the handle.
135 Reference<reference_type> &
136 SAL_CALL operator= (const Reference<reference_type> & handle)
138 return set( handle.m_pBody );
141 #ifdef LIBO_INTERNAL_ONLY
142 /** Assignment.
143 * Unbinds this instance from its body (if bound),
144 * bind it to the body represented by the handle, and
145 * set the body represented by the handle to nullptr.
147 Reference<reference_type> &
148 operator= (Reference<reference_type> && handle)
150 // self-movement guts ourself
151 if (m_pBody)
152 m_pBody->release();
153 m_pBody = handle.m_pBody;
154 handle.m_pBody = nullptr;
155 return *this;
157 #endif
159 /** Assignment...
161 Reference<reference_type> &
162 SAL_CALL operator= (reference_type * pBody)
164 return set( pBody );
167 /** Unbind the body from this handle.
168 Note that for a handle representing a large body,
169 "handle.clear().set(new body());" _might_
170 perform a little bit better than "handle.set(new body());",
171 since in the second case two large objects exist in memory
172 (the old body and the new body).
174 Reference<reference_type> & SAL_CALL clear()
176 if (m_pBody)
178 reference_type * const pOld = m_pBody;
179 m_pBody = NULL;
180 pOld->release();
182 return *this;
186 /** Get the body. Can be used instead of operator->().
187 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
188 are the same.
190 reference_type * SAL_CALL get() const
192 return m_pBody;
196 /** Probably most common used: handle->someBodyOp().
198 reference_type * SAL_CALL operator->() const
200 assert(m_pBody != NULL);
201 return m_pBody;
205 /** Allows (*handle).someBodyOp().
207 reference_type & SAL_CALL operator*() const
209 assert(m_pBody != NULL);
210 return *m_pBody;
214 /** Returns True if the handle does point to a valid body.
216 bool SAL_CALL is() const
218 return (m_pBody != NULL);
221 #if defined LIBO_INTERNAL_ONLY
222 /** Returns True if the handle does point to a valid body.
224 explicit operator bool() const
226 return is();
228 #endif
230 /** Returns True if this points to pBody.
232 bool SAL_CALL operator== (const reference_type * pBody) const
234 return (m_pBody == pBody);
238 /** Returns True if handle points to the same body.
240 bool
241 SAL_CALL operator== (const Reference<reference_type> & handle) const
243 return (m_pBody == handle.m_pBody);
247 /** Needed to place References into STL collection.
249 bool
250 SAL_CALL operator!= (const Reference<reference_type> & handle) const
252 return (m_pBody != handle.m_pBody);
256 /** Needed to place References into STL collection.
258 bool
259 SAL_CALL operator< (const Reference<reference_type> & handle) const
261 return (m_pBody < handle.m_pBody);
265 /** Needed to place References into STL collection.
267 bool
268 SAL_CALL operator> (const Reference<reference_type> & handle) const
270 return (m_pBody > handle.m_pBody);
274 } // namespace rtl
276 #if defined LIBO_INTERNAL_ONLY
277 namespace std
280 /// @cond INTERNAL
282 Make rtl::Reference hashable by default for use in STL containers.
284 @since LibreOffice 6.3
286 template<typename T>
287 struct hash<::rtl::Reference<T>>
289 std::size_t operator()(::rtl::Reference<T> const & s) const
290 { return std::size_t(s.get()); }
292 /// @endcond
296 #endif
298 #endif /* ! INCLUDED_RTL_REF_HXX */
300 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */