1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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_H
24 #define INCLUDED_COM_SUN_STAR_UNO_REFERENCE_H
26 #include "sal/config.h"
31 #if defined LIBO_INTERNAL_ONLY
32 #include <type_traits>
35 #include "rtl/alloc.h"
46 class RuntimeException
;
51 /** Enum defining UNO_REF_NO_ACQUIRE for setting reference without acquiring a given interface.
52 Deprecated, please use SAL_NO_ACQUIRE.
55 enum UnoReference_NoAcquire
57 /** This enum value can be used for creating a reference granting a given interface,
58 i.e. transferring ownership to it.
63 /** This base class serves as a base class for all template reference classes and
64 has been introduced due to compiler problems with templated operators ==, =!.
69 /** the interface pointer
71 XInterface
* _pInterface
;
73 /** Queries given interface for type rType.
75 @param pInterface interface pointer
76 @param rType interface type
77 @return interface of demanded type (may be null)
79 inline static XInterface
* SAL_CALL
iquery( XInterface
* pInterface
, const Type
& rType
);
80 /** Queries given interface for type rType.
81 Throws a RuntimeException if the demanded interface cannot be queried.
83 @param pInterface interface pointer
84 @param rType interface type
85 @return interface of demanded type
87 inline static XInterface
* SAL_CALL
iquery_throw( XInterface
* pInterface
, const Type
& rType
);
90 /** Gets interface pointer. This call does not acquire the interface.
92 @return UNacquired interface pointer
94 XInterface
* SAL_CALL
get() const
95 { return _pInterface
; }
97 /** Checks if reference is null.
99 @return true if reference acquires an interface, i.e. true if it is not null
101 bool SAL_CALL
is() const
102 { return (NULL
!= _pInterface
); }
104 #if defined LIBO_INTERNAL_ONLY
105 /** Checks if reference is null.
107 @return true if reference acquires an interface, i.e. true if it is not null
109 explicit operator bool() const
113 /** Equality operator: compares two interfaces
114 Checks if both references are null or refer to the same object.
116 @param pInterface another interface
117 @return true if both references are null or refer to the same object, false otherwise
119 inline bool SAL_CALL
operator == ( XInterface
* pInterface
) const;
120 /** Inequality operator: compares two interfaces
121 Checks if both references are null or refer to the same object.
123 @param pInterface another interface
124 @return false if both references are null or refer to the same object, true otherwise
126 inline bool SAL_CALL
operator != ( XInterface
* pInterface
) const;
128 /** Equality operator: compares two interfaces
129 Checks if both references are null or refer to the same object.
131 @param rRef another reference
132 @return true if both references are null or refer to the same object, false otherwise
134 inline bool SAL_CALL
operator == ( const BaseReference
& rRef
) const;
135 /** Inequality operator: compares two interfaces
136 Checks if both references are null or refer to the same object.
138 @param rRef another reference
139 @return false if both references are null or refer to the same object, true otherwise
141 inline bool SAL_CALL
operator != ( const BaseReference
& rRef
) const;
143 /** Needed by some STL containers.
145 @param rRef another reference
146 @return true, if this reference is less than rRef
148 inline bool SAL_CALL
operator < ( const BaseReference
& rRef
) const;
151 /** Enum defining UNO_QUERY for implicit interface query.
153 enum UnoReference_Query
155 /** This enum value can be used for implicit interface query.
159 /** Enum defining UNO_QUERY_THROW for implicit interface query.
160 If the demanded interface is unavailable, then a RuntimeException is thrown.
162 enum UnoReference_QueryThrow
164 /** This enum value can be used for implicit interface query.
168 /** Enum defining UNO_SET_THROW for throwing if attempts are made to assign a null
173 enum UnoReference_SetThrow
178 /** Template reference class for interface type derived from BaseReference.
179 A special constructor given the UNO_QUERY identifier queries interfaces
182 template< class interface_type
>
183 class SAL_DLLPUBLIC_RTTI Reference
: public BaseReference
185 /** Queries given interface for type interface_type.
187 @param pInterface interface pointer
188 @return interface of demanded type (may be null)
190 inline static XInterface
* SAL_CALL
iquery( XInterface
* pInterface
);
191 /** Queries given interface for type interface_type.
192 Throws a RuntimeException if the demanded interface cannot be queried.
194 @param pInterface interface pointer
195 @return interface of demanded type
197 inline static XInterface
* SAL_CALL
iquery_throw( XInterface
* pInterface
);
198 /** Returns the given interface if it is not <NULL/>, throws a RuntimeException otherwise.
200 @param pInterface interface pointer
203 inline static interface_type
* SAL_CALL
iset_throw( interface_type
* pInterface
);
205 /** Cast from an "interface pointer" (e.g., BaseReference::_pInterface) to a
206 pointer to this interface_type.
208 To work around ambiguities in the case of multiple-inheritance interface
209 types (which inherit XInterface more than once), use reinterpret_cast
210 (resp. a sequence of two static_casts, to avoid warnings about
211 reinterpret_cast used between related classes) to switch from a pointer
212 to XInterface to a pointer to this derived interface_type. In
213 principle, this is not guaranteed to work. In practice, it seems to
214 work on all supported platforms.
216 static interface_type
* castFromXInterface(XInterface
* p
) {
217 return static_cast< interface_type
* >(static_cast< void * >(p
));
220 /** Cast from a pointer to this interface_type to an "interface pointer"
221 (e.g., BaseReference::_pInterface).
223 To work around ambiguities in the case of multiple-inheritance interface
224 types (which inherit XInterface more than once), use reinterpret_cast
225 (resp. a sequence of two static_casts, to avoid warnings about
226 reinterpret_cast used between related classes) to switch from a pointer
227 to this derived interface_type to a pointer to XInterface. In
228 principle, this is not guaranteed to work. In practice, it seems to
229 work on all supported platforms.
231 static XInterface
* castToXInterface(interface_type
* p
) {
232 return static_cast< XInterface
* >(static_cast< void * >(p
));
237 // these are here to force memory de/allocation to sal lib.
238 static void * SAL_CALL
operator new ( ::size_t nSize
)
239 { return ::rtl_allocateMemory( nSize
); }
240 static void SAL_CALL
operator delete ( void * pMem
)
241 { ::rtl_freeMemory( pMem
); }
242 static void * SAL_CALL
operator new ( ::size_t, void * pMem
)
244 static void SAL_CALL
operator delete ( void *, void * )
248 /** Destructor: Releases interface if set.
250 inline ~Reference() COVERITY_NOEXCEPT_FALSE
;
252 /** Default Constructor: Sets null reference.
256 /** Copy constructor: Copies interface reference.
258 @param rRef another reference
260 inline Reference( const Reference
< interface_type
> & rRef
);
262 #if defined LIBO_INTERNAL_ONLY
265 @param rRef another reference
267 #if !defined(__COVERITY__) // suppress COPY_INSTEAD_OF_MOVE suggestions
268 inline Reference( Reference
< interface_type
> && rRef
) noexcept
;
271 /** Up-casting conversion constructor: Copies interface reference.
273 Does not work for up-casts to ambiguous bases. For the special case of
274 up-casting to Reference< XInterface >, see the corresponding conversion
277 @param rRef another reference
279 template< class derived_type
>
281 const Reference
< derived_type
> & rRef
,
283 std::is_base_of_v
<interface_type
, derived_type
>
284 && !std::is_same_v
<interface_type
, XInterface
>, void *> = nullptr);
287 /** Constructor: Sets given interface pointer.
289 @param pInterface an interface pointer
291 inline Reference( interface_type
* pInterface
);
293 /** Constructor: Sets given interface pointer without acquiring it.
295 @param pInterface another reference
296 @param dummy SAL_NO_ACQUIRE to force obvious distinction to other constructors
298 inline Reference( interface_type
* pInterface
, __sal_NoAcquire dummy
);
299 /** Constructor: Sets given interface pointer without acquiring it.
300 Deprecated, please use SAL_NO_ACQUIRE version.
303 @param pInterface another reference
304 @param dummy UNO_REF_NO_ACQUIRE to force obvious distinction to other constructors
306 inline SAL_DEPRECATED("use SAL_NO_ACQUIRE version") Reference( interface_type
* pInterface
, UnoReference_NoAcquire dummy
);
308 /** Constructor: Queries given interface for reference interface type (interface_type).
310 @param rRef another reference
311 @param dummy UNO_QUERY to force obvious distinction to other constructors
313 inline Reference( const BaseReference
& rRef
, UnoReference_Query dummy
);
314 /** Constructor: Queries given interface for reference interface type (interface_type).
316 @param pInterface an interface pointer
317 @param dummy UNO_QUERY to force obvious distinction to other constructors
319 inline Reference( XInterface
* pInterface
, UnoReference_Query dummy
);
320 /** Constructor: Queries given any for reference interface type (interface_type).
323 @param dummy UNO_QUERY to force obvious distinction to other constructors
325 inline Reference( const Any
& rAny
, UnoReference_Query dummy
);
326 /** Constructor: Queries given interface for reference interface type (interface_type).
327 Throws a RuntimeException if the demanded interface cannot be queried.
329 @param rRef another reference
330 @param dummy UNO_QUERY_THROW to force obvious distinction
331 to other constructors
333 inline Reference( const BaseReference
& rRef
, UnoReference_QueryThrow dummy
);
334 #ifdef LIBO_INTERNAL_ONLY
336 Prevent code from calling the QUERY_THROW constructor, when they meant to use the SET_THROW constructor.
338 Reference( const Reference
< interface_type
> & rRef
, UnoReference_QueryThrow dummy
) = delete;
340 /** Constructor: Queries given interface for reference interface type (interface_type).
341 Throws a RuntimeException if the demanded interface cannot be queried.
343 @param pInterface an interface pointer
344 @param dummy UNO_QUERY_THROW to force obvious distinction
345 to other constructors
347 inline Reference( XInterface
* pInterface
, UnoReference_QueryThrow dummy
);
348 /** Constructor: Queries given any for reference interface type (interface_type).
349 Throws a RuntimeException if the demanded interface cannot be queried.
352 @param dummy UNO_QUERY_THROW to force obvious distinction
353 to other constructors
355 inline Reference( const Any
& rAny
, UnoReference_QueryThrow dummy
);
356 /** Constructor: assigns from the given interface of the same type. Throws a RuntimeException
357 if the source interface is NULL.
359 @param rRef another interface reference of the same type
360 @param dummy UNO_SET_THROW to distinguish from default copy constructor
364 inline Reference( const Reference
< interface_type
> & rRef
, UnoReference_SetThrow dummy
);
365 /** Constructor: assigns from the given interface of the same type. Throws a RuntimeException
366 if the source interface is NULL.
368 @param pInterface an interface pointer
369 @param dummy UNO_SET_THROW to distinguish from default assignment constructor
373 inline Reference( interface_type
* pInterface
, UnoReference_SetThrow dummy
);
375 /** Cast operator to Reference< XInterface >: Reference objects are binary compatible and
376 any interface must be derived from com.sun.star.uno.XInterface.
377 This a useful direct cast possibility.
379 SAL_CALL
operator const Reference
< XInterface
> & () const
380 { return * reinterpret_cast< const Reference
< XInterface
> * >( this ); }
382 /** Dereference operator: Used to call interface methods.
384 @return UNacquired interface pointer
386 interface_type
* SAL_CALL
operator -> () const {
387 assert(_pInterface
!= NULL
);
388 return castFromXInterface(_pInterface
);
391 /** Indirection operator.
393 @since LibreOffice 6.3
394 @return UNacquired interface reference
396 interface_type
& SAL_CALL
operator * () const {
397 assert(_pInterface
!= NULL
);
398 return *castFromXInterface(_pInterface
);
401 /** Gets interface pointer. This call does not acquire the interface.
403 @return UNacquired interface pointer
405 interface_type
* SAL_CALL
get() const
406 { return castFromXInterface(_pInterface
); }
408 /** Clears reference, i.e. releases interface. Reference is null after clear() call.
410 inline void SAL_CALL
clear();
412 /** Sets the given interface. An interface already set will be released.
414 @param rRef another reference
415 @return true, if non-null interface was set
417 inline bool SAL_CALL
set( const Reference
< interface_type
> & rRef
);
418 /** Sets the given interface. An interface already set will be released.
420 @param pInterface another interface
421 @return true, if non-null interface was set
423 inline bool SAL_CALL
set( interface_type
* pInterface
);
425 /** Sets interface pointer without acquiring it. An interface already set will be released.
427 @param pInterface an interface pointer
428 @param dummy SAL_NO_ACQUIRE to force obvious distinction to set methods
429 @return true, if non-null interface was set
431 inline bool SAL_CALL
set( interface_type
* pInterface
, __sal_NoAcquire dummy
);
432 /** Sets interface pointer without acquiring it. An interface already set will be released.
433 Deprecated, please use SAL_NO_ACQUIRE version.
436 @param pInterface an interface pointer
437 @param dummy UNO_REF_NO_ACQUIRE to force obvious distinction to set methods
438 @return true, if non-null interface was set
440 inline SAL_DEPRECATED("use SAL_NO_ACQUIRE version") bool SAL_CALL
set( interface_type
* pInterface
, UnoReference_NoAcquire dummy
);
442 /** Queries given interface for reference interface type (interface_type) and sets it.
443 An interface already set will be released.
445 @param pInterface an interface pointer
446 @param dummy UNO_QUERY to force obvious distinction to set methods
447 @return true, if non-null interface was set
449 inline bool SAL_CALL
set( XInterface
* pInterface
, UnoReference_Query dummy
);
450 /** Queries given interface for reference interface type (interface_type) and sets it.
451 An interface already set will be released.
453 @param rRef another reference
454 @param dummy UNO_QUERY to force obvious distinction to set methods
455 @return true, if non-null interface was set
457 inline bool SAL_CALL
set( const BaseReference
& rRef
, UnoReference_Query dummy
);
459 /** Queries given any for reference interface type (interface_type)
460 and sets it. An interface already set will be released.
463 an Any containing an interface
465 UNO_QUERY to force obvious distinction
468 true, if non-null interface was set
470 inline bool set( Any
const & rAny
, UnoReference_Query dummy
);
472 /** Queries given interface for reference interface type (interface_type) and sets it.
473 An interface already set will be released.
474 Throws a RuntimeException if the demanded interface cannot be set.
476 @param pInterface an interface pointer
477 @param dummy UNO_QUERY_THROW to force obvious distinction
480 inline void SAL_CALL
set( XInterface
* pInterface
, UnoReference_QueryThrow dummy
);
481 /** Queries given interface for reference interface type (interface_type) and sets it.
482 An interface already set will be released.
483 Throws a RuntimeException if the demanded interface cannot be set.
485 @param rRef another reference
486 @param dummy UNO_QUERY_THROW to force obvious distinction
489 inline void SAL_CALL
set( const BaseReference
& rRef
, UnoReference_QueryThrow dummy
);
490 #ifdef LIBO_INTERNAL_ONLY
492 Prevent code from calling the QUERY_THROW version, when they meant to use the SET_THROW version.
494 void set( const Reference
< interface_type
> & rRef
, UnoReference_QueryThrow dummy
) = delete;
497 /** Queries given any for reference interface type (interface_type) and
498 sets it. An interface already set will be released.
499 Throws a RuntimeException if the demanded interface cannot be set.
502 an Any containing an interface
504 UNO_QUERY_THROW to force obvious distinction to set methods
506 inline void set( Any
const & rAny
, UnoReference_QueryThrow dummy
);
507 /** sets the given interface
508 An interface already set will be released.
509 Throws a RuntimeException if the source interface is @b NULL.
511 @param pInterface an interface pointer
512 @param dummy UNO_SET_THROW to force obvious distinction to other set methods
516 inline void SAL_CALL
set( interface_type
* pInterface
, UnoReference_SetThrow dummy
);
517 /** sets the given interface
518 An interface already set will be released.
519 Throws a RuntimeException if the source interface is @b NULL.
521 @param rRef an interface reference
522 @param dummy UNO_SET_THROW to force obvious distinction to other set methods
526 inline void SAL_CALL
set( const Reference
< interface_type
> & rRef
, UnoReference_SetThrow dummy
);
529 /** Assignment operator: Acquires given interface pointer and sets reference.
530 An interface already set will be released.
532 @param pInterface an interface pointer
533 @return this reference
535 inline Reference
< interface_type
> & SAL_CALL
operator = ( interface_type
* pInterface
);
536 /** Assignment operator: Acquires given interface reference and sets reference.
537 An interface already set will be released.
539 @param rRef an interface reference
540 @return this reference
542 inline Reference
< interface_type
> & SAL_CALL
operator = ( const Reference
< interface_type
> & rRef
);
543 #if defined LIBO_INTERNAL_ONLY
544 /** Assignment move operator: Acquires given interface reference and sets reference.
545 An interface already set will be released.
547 @param rRef an interface reference
548 @return this reference
550 inline Reference
< interface_type
> & operator = ( Reference
< interface_type
> && rRef
) noexcept
;
552 /** Queries given interface reference for type interface_type.
554 @param rRef interface reference
555 @return interface reference of demanded type (may be null)
557 SAL_WARN_UNUSED_RESULT
inline static Reference
< interface_type
> SAL_CALL
query( const BaseReference
& rRef
);
558 /** Queries given interface for type interface_type.
560 @param pInterface interface pointer
561 @return interface reference of demanded type (may be null)
563 SAL_WARN_UNUSED_RESULT
inline static Reference
< interface_type
> SAL_CALL
query( XInterface
* pInterface
);
564 #if defined LIBO_INTERNAL_ONLY
565 /** Queries this for the required interface, and returns the requested reference, possibly empty.
566 A syntactic sugar for 'Reference< other_type > xOther(xThis, UNO_QUERY)' that avoids some
569 @return new reference
571 template< class other_type
> inline Reference
< other_type
> query() const;
572 /** Queries this for the required interface, and returns the requested reference, or throws
573 on failure. A syntactic sugar for 'Reference< other_type > xOther(xThis, UNO_QUERY_THROW)'
574 that avoids some verbocity.
576 @return new reference
578 template< class other_type
> inline Reference
< other_type
> queryThrow() const;
589 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */