cid#1607171 Data race condition
[LibreOffice.git] / include / com / sun / star / uno / Reference.hxx
blob900170cf802d2e6eb75d6789bd8a34a20904e6ab
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 .
21 * This file is part of LibreOffice published API.
23 #ifndef INCLUDED_COM_SUN_STAR_UNO_REFERENCE_HXX
24 #define INCLUDED_COM_SUN_STAR_UNO_REFERENCE_HXX
26 #include "sal/config.h"
28 #include <cstddef>
29 #include <ostream>
31 #include "com/sun/star/uno/Reference.h"
32 #include "com/sun/star/uno/RuntimeException.hpp"
33 #include "com/sun/star/uno/XInterface.hpp"
34 #include "com/sun/star/uno/Any.hxx"
35 #include "cppu/cppudllapi.h"
37 extern "C" CPPU_DLLPUBLIC rtl_uString * SAL_CALL cppu_unsatisfied_iquery_msg(
38 typelib_TypeDescriptionReference * pType )
39 SAL_THROW_EXTERN_C();
40 extern "C" CPPU_DLLPUBLIC rtl_uString * SAL_CALL cppu_unsatisfied_iset_msg(
41 typelib_TypeDescriptionReference * pType )
42 SAL_THROW_EXTERN_C();
44 namespace com
46 namespace sun
48 namespace star
50 namespace uno
54 inline XInterface * BaseReference::iquery(
55 XInterface * pInterface, const Type & rType )
57 if (pInterface)
59 Any aRet( pInterface->queryInterface( rType ) );
60 if (typelib_TypeClass_INTERFACE == aRet.pType->eTypeClass)
62 XInterface * pRet = static_cast< XInterface * >( aRet.pReserved );
63 aRet.pReserved = NULL;
64 return pRet;
67 return NULL;
70 template< class interface_type >
71 inline XInterface * Reference< interface_type >::iquery(
72 XInterface * pInterface )
74 return BaseReference::iquery(pInterface, interface_type::static_type());
77 inline XInterface * BaseReference::iquery_throw(
78 XInterface * pInterface, const Type & rType )
80 XInterface * pQueried = iquery( pInterface, rType );
81 if (pQueried)
82 return pQueried;
83 throw RuntimeException(
84 ::rtl::OUString( cppu_unsatisfied_iquery_msg( rType.getTypeLibType() ), SAL_NO_ACQUIRE ),
85 Reference< XInterface >( pInterface ) );
88 template< class interface_type >
89 inline XInterface * Reference< interface_type >::iquery_throw(
90 XInterface * pInterface )
92 return BaseReference::iquery_throw(
93 pInterface, interface_type::static_type());
96 template< class interface_type >
97 inline interface_type * Reference< interface_type >::iset_throw(
98 interface_type * pInterface )
100 if (pInterface)
102 castToXInterface(pInterface)->acquire();
103 return pInterface;
105 throw RuntimeException(
106 ::rtl::OUString( cppu_unsatisfied_iset_msg( interface_type::static_type().getTypeLibType() ), SAL_NO_ACQUIRE ),
107 NULL );
110 template< class interface_type >
111 inline Reference< interface_type >::~Reference() COVERITY_NOEXCEPT_FALSE
113 if (_pInterface)
114 _pInterface->release();
117 template< class interface_type >
118 inline Reference< interface_type >::Reference()
120 _pInterface = NULL;
123 template< class interface_type >
124 inline Reference< interface_type >::Reference( const Reference< interface_type > & rRef )
126 _pInterface = rRef._pInterface;
127 if (_pInterface)
128 _pInterface->acquire();
131 #if defined LIBO_INTERNAL_ONLY
133 #if !defined(__COVERITY__)
134 template< class interface_type >
135 inline Reference< interface_type >::Reference( Reference< interface_type > && rRef ) noexcept
137 _pInterface = rRef._pInterface;
138 rRef._pInterface = nullptr;
140 #endif
142 template< class interface_type > template< class derived_type >
143 inline Reference< interface_type >::Reference(
144 const Reference< derived_type > & rRef,
145 std::enable_if_t<
146 std::is_base_of_v<interface_type, derived_type>
147 && !std::is_same_v<interface_type, XInterface>, void *>)
149 interface_type * p = rRef.get();
150 _pInterface = castToXInterface(p);
151 if (_pInterface)
152 _pInterface->acquire();
154 #endif
156 template< class interface_type >
157 inline Reference< interface_type >::Reference( interface_type * pInterface )
159 _pInterface = castToXInterface(pInterface);
160 if (_pInterface)
161 _pInterface->acquire();
164 template< class interface_type >
165 inline Reference< interface_type >::Reference( interface_type * pInterface, __sal_NoAcquire )
167 _pInterface = castToXInterface(pInterface);
170 template< class interface_type >
171 inline Reference< interface_type >::Reference( interface_type * pInterface, UnoReference_NoAcquire )
173 _pInterface = castToXInterface(pInterface);
176 template< class interface_type >
177 inline Reference< interface_type >::Reference( const BaseReference & rRef, UnoReference_Query )
179 _pInterface = iquery( rRef.get() );
182 template< class interface_type >
183 inline Reference< interface_type >::Reference( XInterface * pInterface, UnoReference_Query )
185 _pInterface = iquery( pInterface );
188 template< class interface_type >
189 inline Reference< interface_type >::Reference( const Any & rAny, UnoReference_Query )
191 _pInterface = (typelib_TypeClass_INTERFACE == rAny.pType->eTypeClass
192 ? iquery( static_cast< XInterface * >( rAny.pReserved ) ) : NULL);
195 template< class interface_type >
196 inline Reference< interface_type >::Reference( const BaseReference & rRef, UnoReference_QueryThrow )
198 _pInterface = iquery_throw( rRef.get() );
201 template< class interface_type >
202 inline Reference< interface_type >::Reference( XInterface * pInterface, UnoReference_QueryThrow )
204 _pInterface = iquery_throw( pInterface );
207 template< class interface_type >
208 inline Reference< interface_type >::Reference( const Any & rAny, UnoReference_QueryThrow )
210 _pInterface = iquery_throw( typelib_TypeClass_INTERFACE == rAny.pType->eTypeClass
211 ? static_cast< XInterface * >( rAny.pReserved ) : NULL );
214 template< class interface_type >
215 inline Reference< interface_type >::Reference( const Reference< interface_type > & rRef, UnoReference_SetThrow )
217 _pInterface = castToXInterface( iset_throw( rRef.get() ) );
220 template< class interface_type >
221 inline Reference< interface_type >::Reference( interface_type * pInterface, UnoReference_SetThrow )
223 _pInterface = castToXInterface( iset_throw( pInterface ) );
227 template< class interface_type >
228 inline void Reference< interface_type >::clear()
230 if (_pInterface)
232 XInterface * const pOld = _pInterface;
233 _pInterface = NULL;
234 pOld->release();
238 template< class interface_type >
239 inline bool Reference< interface_type >::set(
240 interface_type * pInterface )
242 if (pInterface)
243 castToXInterface(pInterface)->acquire();
244 XInterface * const pOld = _pInterface;
245 _pInterface = castToXInterface(pInterface);
246 if (pOld)
247 pOld->release();
248 return (NULL != pInterface);
251 template< class interface_type >
252 inline bool Reference< interface_type >::set(
253 interface_type * pInterface, __sal_NoAcquire )
255 XInterface * const pOld = _pInterface;
256 _pInterface = castToXInterface(pInterface);
257 if (pOld)
258 pOld->release();
259 return (NULL != pInterface);
262 template< class interface_type >
263 inline bool Reference< interface_type >::set(
264 interface_type * pInterface, UnoReference_NoAcquire )
266 return set( pInterface, SAL_NO_ACQUIRE );
270 template< class interface_type >
271 inline bool Reference< interface_type >::set(
272 const Reference< interface_type > & rRef )
274 return set( castFromXInterface( rRef._pInterface ) );
277 template< class interface_type >
278 inline bool Reference< interface_type >::set(
279 XInterface * pInterface, UnoReference_Query )
281 return set( castFromXInterface(iquery( pInterface )), SAL_NO_ACQUIRE );
284 template< class interface_type >
285 inline bool Reference< interface_type >::set(
286 const BaseReference & rRef, UnoReference_Query )
288 return set( castFromXInterface(iquery( rRef.get() )), SAL_NO_ACQUIRE );
292 template< class interface_type >
293 inline bool Reference< interface_type >::set(
294 Any const & rAny, UnoReference_Query )
296 return set(
297 castFromXInterface(
298 iquery(
299 rAny.pType->eTypeClass == typelib_TypeClass_INTERFACE
300 ? static_cast< XInterface * >( rAny.pReserved ) : NULL )),
301 SAL_NO_ACQUIRE );
305 template< class interface_type >
306 inline void Reference< interface_type >::set(
307 XInterface * pInterface, UnoReference_QueryThrow )
309 set( castFromXInterface(iquery_throw( pInterface )), SAL_NO_ACQUIRE );
312 template< class interface_type >
313 inline void Reference< interface_type >::set(
314 const BaseReference & rRef, UnoReference_QueryThrow )
316 set( castFromXInterface(iquery_throw( rRef.get() )), SAL_NO_ACQUIRE );
320 template< class interface_type >
321 inline void Reference< interface_type >::set(
322 Any const & rAny, UnoReference_QueryThrow )
324 set( castFromXInterface(
325 iquery_throw(
326 rAny.pType->eTypeClass == typelib_TypeClass_INTERFACE
327 ? static_cast< XInterface * >( rAny.pReserved ) : NULL )),
328 SAL_NO_ACQUIRE );
331 template< class interface_type >
332 inline void Reference< interface_type >::set(
333 interface_type * pInterface, UnoReference_SetThrow )
335 set( iset_throw( pInterface ), SAL_NO_ACQUIRE );
338 template< class interface_type >
339 inline void Reference< interface_type >::set(
340 const Reference< interface_type > & rRef, UnoReference_SetThrow )
342 set( rRef.get(), UNO_SET_THROW );
346 template< class interface_type >
347 inline Reference< interface_type > & Reference< interface_type >::operator = (
348 interface_type * pInterface )
350 set( pInterface );
351 return *this;
354 template< class interface_type >
355 inline Reference< interface_type > & Reference< interface_type >::operator = (
356 const Reference< interface_type > & rRef )
358 set( castFromXInterface( rRef._pInterface ) );
359 return *this;
362 #if defined LIBO_INTERNAL_ONLY
363 template< class interface_type >
364 inline Reference< interface_type > & Reference< interface_type >::operator = (
365 Reference< interface_type > && rRef ) noexcept
367 if (_pInterface)
368 _pInterface->release();
369 _pInterface = rRef._pInterface;
370 rRef._pInterface = nullptr;
371 return *this;
373 #endif
375 template< class interface_type >
376 inline Reference< interface_type > Reference< interface_type >::query(
377 const BaseReference & rRef )
379 return Reference< interface_type >(
380 castFromXInterface(iquery( rRef.get() )), SAL_NO_ACQUIRE );
383 template< class interface_type >
384 inline Reference< interface_type > Reference< interface_type >::query(
385 XInterface * pInterface )
387 return Reference< interface_type >(
388 castFromXInterface(iquery( pInterface )), SAL_NO_ACQUIRE );
391 #if defined LIBO_INTERNAL_ONLY
392 template< class interface_type > template< class other_type >
393 inline Reference< other_type > Reference< interface_type >::query() const
395 return Reference< other_type >(*this, UNO_QUERY);
398 template< class interface_type > template< class other_type >
399 inline Reference< other_type > Reference< interface_type >::queryThrow() const
401 return Reference< other_type >(*this, UNO_QUERY_THROW);
404 template< class interface_type >
405 inline Reference< interface_type > Any::query() const
407 return Reference< interface_type >(*this, UNO_QUERY);
410 template< class interface_type >
411 inline Reference< interface_type > Any::queryThrow() const
413 return Reference< interface_type >(*this, UNO_QUERY_THROW);
415 #endif
418 inline bool BaseReference::operator == ( XInterface * pInterface ) const
420 if (_pInterface == pInterface)
421 return true;
424 // only the query to XInterface must return the same pointer if they belong to same objects
425 Reference< XInterface > x1( _pInterface, UNO_QUERY );
426 Reference< XInterface > x2( pInterface, UNO_QUERY );
427 return (x1._pInterface == x2._pInterface);
429 catch (RuntimeException &)
431 return false;
436 inline bool BaseReference::operator < (
437 const BaseReference & rRef ) const
439 if (_pInterface == rRef._pInterface)
440 return false;
443 // only the query to XInterface must return the same pointer:
444 Reference< XInterface > x1( _pInterface, UNO_QUERY );
445 Reference< XInterface > x2( rRef, UNO_QUERY );
446 return (x1._pInterface < x2._pInterface);
448 catch (RuntimeException &)
450 return false;
455 inline bool BaseReference::operator != ( XInterface * pInterface ) const
457 return (! operator == ( pInterface ));
460 inline bool BaseReference::operator == ( const BaseReference & rRef ) const
462 return operator == ( rRef._pInterface );
465 inline bool BaseReference::operator != ( const BaseReference & rRef ) const
467 return (! operator == ( rRef._pInterface ));
470 #if defined LIBO_INTERNAL_ONLY
472 Support for BaseReference in std::ostream (and thus in CPPUNIT_ASSERT or
473 SAL_INFO macros, for example).
475 @since LibreOffice 5.4
477 template<typename charT, typename traits> std::basic_ostream<charT, traits> &
478 operator <<(
479 std::basic_ostream<charT, traits> & stream, BaseReference const & ref)
480 { return stream << ref.get(); }
481 #endif
488 #if defined LIBO_INTERNAL_ONLY
489 namespace std
493 Make css::uno::Reference hashable by default for use in STL containers.
495 @since LibreOffice 6.3
497 template<typename T>
498 struct hash<::css::uno::Reference<T>>
500 std::size_t operator()(::css::uno::Reference<T> const & s) const
501 { return size_t(s.get()); }
506 #endif
508 #endif
510 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */