bump product version to 6.3.0.0.beta1
[LibreOffice.git] / include / rtl / ref.hxx
blob73c03ff7657d862f921ddc331325e6cf6aaf65d6
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>
29 #include "sal/types.h"
31 namespace rtl
34 /** Template reference class for reference type.
36 template <class reference_type>
37 class Reference
39 /** The <b>reference_type</b> body pointer.
41 reference_type * m_pBody;
44 public:
45 /** Constructor...
47 Reference()
48 : m_pBody (NULL)
52 /** Constructor...
54 Reference (reference_type * pBody, __sal_NoAcquire)
55 : m_pBody (pBody)
59 /** Constructor...
61 Reference (reference_type * pBody)
62 : m_pBody (pBody)
64 if (m_pBody)
65 m_pBody->acquire();
68 /** Copy constructor...
70 Reference (const Reference<reference_type> & handle)
71 : m_pBody (handle.m_pBody)
73 if (m_pBody)
74 m_pBody->acquire();
77 #ifdef LIBO_INTERNAL_ONLY
78 /** Move constructor...
80 Reference (Reference<reference_type> && handle)
81 : m_pBody (handle.m_pBody)
83 handle.m_pBody = nullptr;
85 #endif
87 /** Destructor...
89 ~Reference() COVERITY_NOEXCEPT_FALSE
91 if (m_pBody)
92 m_pBody->release();
95 /** Set...
96 Similar to assignment.
98 Reference<reference_type> &
99 SAL_CALL set (reference_type * pBody)
101 if (pBody)
102 pBody->acquire();
103 reference_type * const pOld = m_pBody;
104 m_pBody = pBody;
105 if (pOld)
106 pOld->release();
107 return *this;
110 /** Assignment.
111 Unbinds this instance from its body (if bound) and
112 bind it to the body represented by the handle.
114 Reference<reference_type> &
115 SAL_CALL operator= (const Reference<reference_type> & handle)
117 return set( handle.m_pBody );
120 #ifdef LIBO_INTERNAL_ONLY
121 /** Assignment.
122 * Unbinds this instance from its body (if bound),
123 * bind it to the body represented by the handle, and
124 * set the body represented by the handle to nullptr.
126 Reference<reference_type> &
127 operator= (Reference<reference_type> && handle)
129 // self-movement guts ourself
130 if (m_pBody)
131 m_pBody->release();
132 m_pBody = handle.m_pBody;
133 handle.m_pBody = nullptr;
134 return *this;
136 #endif
138 /** Assignment...
140 Reference<reference_type> &
141 SAL_CALL operator= (reference_type * pBody)
143 return set( pBody );
146 /** Unbind the body from this handle.
147 Note that for a handle representing a large body,
148 "handle.clear().set(new body());" _might_
149 perform a little bit better than "handle.set(new body());",
150 since in the second case two large objects exist in memory
151 (the old body and the new body).
153 Reference<reference_type> & SAL_CALL clear()
155 if (m_pBody)
157 reference_type * const pOld = m_pBody;
158 m_pBody = NULL;
159 pOld->release();
161 return *this;
165 /** Get the body. Can be used instead of operator->().
166 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
167 are the same.
169 reference_type * SAL_CALL get() const
171 return m_pBody;
175 /** Probably most common used: handle->someBodyOp().
177 reference_type * SAL_CALL operator->() const
179 assert(m_pBody != NULL);
180 return m_pBody;
184 /** Allows (*handle).someBodyOp().
186 reference_type & SAL_CALL operator*() const
188 assert(m_pBody != NULL);
189 return *m_pBody;
193 /** Returns True if the handle does point to a valid body.
195 bool SAL_CALL is() const
197 return (m_pBody != NULL);
200 #if defined LIBO_INTERNAL_ONLY
201 /** Returns True if the handle does point to a valid body.
203 explicit operator bool() const
205 return is();
207 #endif
209 /** Returns True if this points to pBody.
211 bool SAL_CALL operator== (const reference_type * pBody) const
213 return (m_pBody == pBody);
217 /** Returns True if handle points to the same body.
219 bool
220 SAL_CALL operator== (const Reference<reference_type> & handle) const
222 return (m_pBody == handle.m_pBody);
226 /** Needed to place References into STL collection.
228 bool
229 SAL_CALL operator!= (const Reference<reference_type> & handle) const
231 return (m_pBody != handle.m_pBody);
235 /** Needed to place References into STL collection.
237 bool
238 SAL_CALL operator< (const Reference<reference_type> & handle) const
240 return (m_pBody < handle.m_pBody);
244 /** Needed to place References into STL collection.
246 bool
247 SAL_CALL operator> (const Reference<reference_type> & handle) const
249 return (m_pBody > handle.m_pBody);
253 } // namespace rtl
255 #if defined LIBO_INTERNAL_ONLY
256 namespace std
259 /// @cond INTERNAL
261 Make rtl::Reference hashable by default for use in STL containers.
263 @since LibreOffice 6.3
265 template<typename T>
266 struct hash<::rtl::Reference<T>>
268 std::size_t operator()(::rtl::Reference<T> const & s) const
269 { return std::size_t(s.get()); }
271 /// @endcond
275 #endif
277 #endif /* ! INCLUDED_RTL_REF_HXX */
279 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */