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 .
19 #ifndef INCLUDED_COM_SUN_STAR_UNO_REFERENCE_H
20 #define INCLUDED_COM_SUN_STAR_UNO_REFERENCE_H
22 #include "sal/config.h"
27 #include "rtl/alloc.h"
38 class RuntimeException
;
43 /** Enum defining UNO_REF_NO_ACQUIRE for setting reference without acquiring a given interface.
44 Deprecated, please use SAL_NO_ACQUIRE.
47 enum UnoReference_NoAcquire
49 /** This enum value can be used for creating a reference granting a given interface,
50 i.e. transferring ownership to it.
55 /** This base class serves as a base class for all template reference classes and
56 has been introduced due to compiler problems with templated operators ==, =!.
61 /** the interface pointer
63 XInterface
* _pInterface
;
65 /** Queries given interface for type rType.
67 @param pInterface interface pointer
68 @param rType interface type
69 @return interface of demanded type (may be null)
71 inline static XInterface
* SAL_CALL
iquery( XInterface
* pInterface
, const Type
& rType
);
72 /** Queries given interface for type rType.
73 Throws a RuntimeException if the demanded interface cannot be queried.
75 @param pInterface interface pointer
76 @param rType interface type
77 @return interface of demanded type
79 inline static XInterface
* SAL_CALL
iquery_throw( XInterface
* pInterface
, const Type
& rType
);
82 /** Gets interface pointer. This call does not acquire the interface.
84 @return UNacquired interface pointer
86 XInterface
* SAL_CALL
get() const
87 { return _pInterface
; }
89 /** Checks if reference is null.
91 @return true if reference acquires an interface, i.e. true if it is not null
93 bool SAL_CALL
is() const
94 { return (NULL
!= _pInterface
); }
96 #if defined LIBO_INTERNAL_ONLY
97 /** Checks if reference is null.
99 @return true if reference acquires an interface, i.e. true if it is not null
101 explicit operator bool() const
105 /** Equality operator: compares two interfaces
106 Checks if both references are null or refer to the same object.
108 @param pInterface another interface
109 @return true if both references are null or refer to the same object, false otherwise
111 inline bool SAL_CALL
operator == ( XInterface
* pInterface
) const;
112 /** Unequality operator: compares two interfaces
113 Checks if both references are null or refer to the same object.
115 @param pInterface another interface
116 @return false if both references are null or refer to the same object, true otherwise
118 inline bool SAL_CALL
operator != ( XInterface
* pInterface
) const;
120 /** Equality operator: compares two interfaces
121 Checks if both references are null or refer to the same object.
123 @param rRef another reference
124 @return true if both references are null or refer to the same object, false otherwise
126 inline bool SAL_CALL
operator == ( const BaseReference
& rRef
) const;
127 /** Unequality operator: compares two interfaces
128 Checks if both references are null or refer to the same object.
130 @param rRef another reference
131 @return false if both references are null or refer to the same object, true otherwise
133 inline bool SAL_CALL
operator != ( const BaseReference
& rRef
) const;
135 /** Needed by some STL containers.
137 @param rRef another reference
138 @return true, if this reference is less than rRef
140 inline bool SAL_CALL
operator < ( const BaseReference
& rRef
) const;
143 /** Enum defining UNO_QUERY for implicit interface query.
145 enum UnoReference_Query
147 /** This enum value can be used for implicit interface query.
151 /** Enum defining UNO_QUERY_THROW for implicit interface query.
152 If the demanded interface is unavailable, then a RuntimeException is thrown.
154 enum UnoReference_QueryThrow
156 /** This enum value can be used for implicit interface query.
160 /** Enum defining UNO_SET_THROW for throwing if attempts are made to assign a null
165 enum UnoReference_SetThrow
173 // A mechanism to enable up-casts, used by the Reference conversion constructor,
174 // but at the same time disable up-casts to XInterface, so that the conversion
175 // operator for that special case is used in an expression like
176 // Reference< XInterface >(x); heavily borrowed from boost::is_base_and_derived
177 // (which manages to avoid compilation problems with ambiguous bases and cites
178 // comp.lang.c++.moderated mail <http://groups.google.com/groups?
179 // selm=df893da6.0301280859.522081f7%40posting.google.com> "SuperSubclass
180 // (is_base_and_derived) complete implementation!" by Rani Sharoni and cites
181 // Aleksey Gurtovoy for the workaround for MSVC), to avoid including Boost
182 // headers in URE headers (could ultimately be based on C++11 std::is_base_of):
184 template< typename T1
, typename T2
> struct UpCast
{
186 template< bool, typename U1
, typename
> struct C
189 template< typename U1
, typename U2
> struct C
< false, U1
, U2
>
192 struct S
{ char c
[2]; };
194 #if defined _MSC_VER && _MSC_VER < 1800
195 static char f(T2
*, long);
196 static S
f(T1
* const &, int);
198 template< typename U
> static char f(T2
*, U
);
199 static S
f(T1
*, int);
203 H(); // avoid C2514 "class has no constructors" from MSVC
204 #if defined _MSC_VER && _MSC_VER < 1800
205 operator T1
* const & () const;
207 operator T1
* () const;
213 typedef typename C
< sizeof (f(H(), 0)) == 1, void *, void >::t t
;
216 template< typename T2
> struct UpCast
< XInterface
, T2
> {};
221 /** Template reference class for interface type derived from BaseReference.
222 A special constructor given the UNO_QUERY identifier queries interfaces
225 template< class interface_type
>
226 class SAL_DLLPUBLIC_RTTI Reference
: public BaseReference
228 /** Queries given interface for type interface_type.
230 @param pInterface interface pointer
231 @return interface of demanded type (may be null)
233 inline static XInterface
* SAL_CALL
iquery( XInterface
* pInterface
);
234 /** Queries given interface for type interface_type.
235 Throws a RuntimeException if the demanded interface cannot be queried.
237 @param pInterface interface pointer
238 @return interface of demanded type
240 inline static XInterface
* SAL_CALL
iquery_throw( XInterface
* pInterface
);
241 /** Returns the given interface if it is not <NULL/>, throws a RuntimeException otherwise.
243 @param pInterface interface pointer
246 inline static interface_type
* SAL_CALL
iset_throw( interface_type
* pInterface
);
248 /** Cast from an "interface pointer" (e.g., BaseReference::_pInterface) to a
249 pointer to this interface_type.
251 To work around ambiguities in the case of multiple-inheritance interface
252 types (which inherit XInterface more than once), use reinterpret_cast
253 (resp. a sequence of two static_casts, to avoid warnings about
254 reinterpret_cast used between related classes) to switch from a pointer
255 to XInterface to a pointer to this derived interface_type. In
256 principle, this is not guaranteed to work. In practice, it seems to
257 work on all supported platforms.
259 static interface_type
* castFromXInterface(XInterface
* p
) {
260 return static_cast< interface_type
* >(static_cast< void * >(p
));
263 /** Cast from a pointer to this interface_type to an "interface pointer"
264 (e.g., BaseReference::_pInterface).
266 To work around ambiguities in the case of multiple-inheritance interface
267 types (which inherit XInterface more than once), use reinterpret_cast
268 (resp. a sequence of two static_casts, to avoid warnings about
269 reinterpret_cast used between related classes) to switch from a pointer
270 to this derived interface_type to a pointer to XInterface. In
271 principle, this is not guaranteed to work. In practice, it seems to
272 work on all supported platforms.
274 static XInterface
* castToXInterface(interface_type
* p
) {
275 return static_cast< XInterface
* >(static_cast< void * >(p
));
280 // these are here to force memory de/allocation to sal lib.
281 static void * SAL_CALL
operator new ( ::size_t nSize
)
282 { return ::rtl_allocateMemory( nSize
); }
283 static void SAL_CALL
operator delete ( void * pMem
)
284 { ::rtl_freeMemory( pMem
); }
285 static void * SAL_CALL
operator new ( ::size_t, void * pMem
)
287 static void SAL_CALL
operator delete ( void *, void * )
291 /** Destructor: Releases interface if set.
293 inline ~Reference() COVERITY_NOEXCEPT_FALSE
;
295 /** Default Constructor: Sets null reference.
299 /** Copy constructor: Copies interface reference.
301 @param rRef another reference
303 inline Reference( const Reference
< interface_type
> & rRef
);
305 #if defined LIBO_INTERNAL_ONLY
308 @param rRef another reference
310 inline Reference( Reference
< interface_type
> && rRef
);
313 /** Up-casting conversion constructor: Copies interface reference.
315 Does not work for up-casts to ambiguous bases. For the special case of
316 up-casting to Reference< XInterface >, see the corresponding conversion
319 @param rRef another reference
321 template< class derived_type
>
323 const Reference
< derived_type
> & rRef
,
324 typename
detail::UpCast
< interface_type
, derived_type
>::t
= 0 );
326 /** Constructor: Sets given interface pointer.
328 @param pInterface an interface pointer
330 inline Reference( interface_type
* pInterface
);
332 /** Constructor: Sets given interface pointer without acquiring it.
334 @param pInterface another reference
335 @param dummy SAL_NO_ACQUIRE to force obvious distinction to other constructors
337 inline Reference( interface_type
* pInterface
, __sal_NoAcquire dummy
);
338 /** Constructor: Sets given interface pointer without acquiring it.
339 Deprecated, please use SAL_NO_ACQUIRE version.
342 @param pInterface another reference
343 @param dummy UNO_REF_NO_ACQUIRE to force obvious distinction to other constructors
345 inline SAL_DEPRECATED("use SAL_NO_ACQUIRE version") Reference( interface_type
* pInterface
, UnoReference_NoAcquire dummy
);
347 /** Constructor: Queries given interface for reference interface type (interface_type).
349 @param rRef another reference
350 @param dummy UNO_QUERY to force obvious distinction to other constructors
352 inline Reference( const BaseReference
& rRef
, UnoReference_Query dummy
);
353 /** Constructor: Queries given interface for reference interface type (interface_type).
355 @param pInterface an interface pointer
356 @param dummy UNO_QUERY to force obvious distinction to other constructors
358 inline Reference( XInterface
* pInterface
, UnoReference_Query dummy
);
359 /** Constructor: Queries given any for reference interface type (interface_type).
362 @param dummy UNO_QUERY to force obvious distinction to other constructors
364 inline Reference( const Any
& rAny
, UnoReference_Query dummy
);
365 /** Constructor: Queries given interface for reference interface type (interface_type).
366 Throws a RuntimeException if the demanded interface cannot be queried.
368 @param rRef another reference
369 @param dummy UNO_QUERY_THROW to force obvious distinction
370 to other constructors
372 inline Reference( const BaseReference
& rRef
, UnoReference_QueryThrow dummy
);
373 #ifdef LIBO_INTERNAL_ONLY
375 Prevent code from calling the QUERY_THROW constructor, when they meant to use the SET_THROW constructor.
377 Reference( const Reference
< interface_type
> & rRef
, UnoReference_QueryThrow dummy
) = delete;
379 /** Constructor: Queries given interface for reference interface type (interface_type).
380 Throws a RuntimeException if the demanded interface cannot be queried.
382 @param pInterface an interface pointer
383 @param dummy UNO_QUERY_THROW to force obvious distinction
384 to other constructors
386 inline Reference( XInterface
* pInterface
, UnoReference_QueryThrow dummy
);
387 /** Constructor: Queries given any for reference interface type (interface_type).
388 Throws a RuntimeException if the demanded interface cannot be queried.
391 @param dummy UNO_QUERY_THROW to force obvious distinction
392 to other constructors
394 inline Reference( const Any
& rAny
, UnoReference_QueryThrow dummy
);
395 /** Constructor: assigns from the given interface of the same type. Throws a RuntimeException
396 if the source interface is NULL.
398 @param rRef another interface reference of the same type
399 @param dummy UNO_SET_THROW to distinguish from default copy constructor
403 inline Reference( const Reference
< interface_type
> & rRef
, UnoReference_SetThrow dummy
);
404 /** Constructor: assigns from the given interface of the same type. Throws a RuntimeException
405 if the source interface is NULL.
407 @param pInterface an interface pointer
408 @param dummy UNO_SET_THROW to distinguish from default assignment constructor
412 inline Reference( interface_type
* pInterface
, UnoReference_SetThrow dummy
);
414 /** Cast operator to Reference< XInterface >: Reference objects are binary compatible and
415 any interface must be derived from com.sun.star.uno.XInterface.
416 This a useful direct cast possibility.
418 SAL_CALL
operator const Reference
< XInterface
> & () const
419 { return * reinterpret_cast< const Reference
< XInterface
> * >( this ); }
421 /** Dereference operator: Used to call interface methods.
423 @return UNacquired interface pointer
425 interface_type
* SAL_CALL
operator -> () const {
426 assert(_pInterface
!= NULL
);
427 return castFromXInterface(_pInterface
);
430 /** Indirection operator.
432 @since LibreOffice 6.3
433 @return UNacquired interface reference
435 interface_type
& SAL_CALL
operator * () const {
436 assert(_pInterface
!= NULL
);
437 return *castFromXInterface(_pInterface
);
440 /** Gets interface pointer. This call does not acquire the interface.
442 @return UNacquired interface pointer
444 interface_type
* SAL_CALL
get() const
445 { return castFromXInterface(_pInterface
); }
447 /** Clears reference, i.e. releases interface. Reference is null after clear() call.
449 inline void SAL_CALL
clear();
451 /** Sets the given interface. An interface already set will be released.
453 @param rRef another reference
454 @return true, if non-null interface was set
456 inline bool SAL_CALL
set( const Reference
< interface_type
> & rRef
);
457 /** Sets the given interface. An interface already set will be released.
459 @param pInterface another interface
460 @return true, if non-null interface was set
462 inline bool SAL_CALL
set( interface_type
* pInterface
);
464 /** Sets interface pointer without acquiring it. An interface already set will be released.
466 @param pInterface an interface pointer
467 @param dummy SAL_NO_ACQUIRE to force obvious distinction to set methods
468 @return true, if non-null interface was set
470 inline bool SAL_CALL
set( interface_type
* pInterface
, __sal_NoAcquire dummy
);
471 /** Sets interface pointer without acquiring it. An interface already set will be released.
472 Deprecated, please use SAL_NO_ACQUIRE version.
475 @param pInterface an interface pointer
476 @param dummy UNO_REF_NO_ACQUIRE to force obvious distinction to set methods
477 @return true, if non-null interface was set
479 inline SAL_DEPRECATED("use SAL_NO_ACQUIRE version") bool SAL_CALL
set( interface_type
* pInterface
, UnoReference_NoAcquire dummy
);
481 /** Queries given interface for reference interface type (interface_type) and sets it.
482 An interface already set will be released.
484 @param pInterface an interface pointer
485 @param dummy UNO_QUERY to force obvious distinction to set methods
486 @return true, if non-null interface was set
488 inline bool SAL_CALL
set( XInterface
* pInterface
, UnoReference_Query dummy
);
489 /** Queries given interface for reference interface type (interface_type) and sets it.
490 An interface already set will be released.
492 @param rRef another reference
493 @param dummy UNO_QUERY to force obvious distinction to set methods
494 @return true, if non-null interface was set
496 inline bool SAL_CALL
set( const BaseReference
& rRef
, UnoReference_Query dummy
);
498 /** Queries given any for reference interface type (interface_type)
499 and sets it. An interface already set will be released.
502 an Any containing an interface
504 UNO_QUERY to force obvious distinction
507 true, if non-null interface was set
509 inline bool set( Any
const & rAny
, UnoReference_Query dummy
);
511 /** Queries given interface for reference interface type (interface_type) and sets it.
512 An interface already set will be released.
513 Throws a RuntimeException if the demanded interface cannot be set.
515 @param pInterface an interface pointer
516 @param dummy UNO_QUERY_THROW to force obvious distinction
519 inline void SAL_CALL
set( XInterface
* pInterface
, UnoReference_QueryThrow dummy
);
520 /** Queries given interface for reference interface type (interface_type) and sets it.
521 An interface already set will be released.
522 Throws a RuntimeException if the demanded interface cannot be set.
524 @param rRef another reference
525 @param dummy UNO_QUERY_THROW to force obvious distinction
528 inline void SAL_CALL
set( const BaseReference
& rRef
, UnoReference_QueryThrow dummy
);
529 #ifdef LIBO_INTERNAL_ONLY
531 Prevent code from calling the QUERY_THROW version, when they meant to use the SET_THROW version.
533 void set( const Reference
< interface_type
> & rRef
, UnoReference_QueryThrow dummy
) = delete;
536 /** Queries given any for reference interface type (interface_type) and
537 sets it. An interface already set will be released.
538 Throws a RuntimeException if the demanded interface cannot be set.
541 an Any containing an interface
543 UNO_QUERY_THROW to force obvious distinction to set methods
545 inline void set( Any
const & rAny
, UnoReference_QueryThrow dummy
);
546 /** sets the given interface
547 An interface already set will be released.
548 Throws a RuntimeException if the source interface is @b NULL.
550 @param pInterface an interface pointer
551 @param dummy UNO_SET_THROW to force obvious distinction to other set methods
555 inline void SAL_CALL
set( interface_type
* pInterface
, UnoReference_SetThrow dummy
);
556 /** sets the given interface
557 An interface already set will be released.
558 Throws a RuntimeException if the source interface is @b NULL.
560 @param rRef an interface reference
561 @param dummy UNO_SET_THROW to force obvious distinction to other set methods
565 inline void SAL_CALL
set( const Reference
< interface_type
> & rRef
, UnoReference_SetThrow dummy
);
568 /** Assignment operator: Acquires given interface pointer and sets reference.
569 An interface already set will be released.
571 @param pInterface an interface pointer
572 @return this reference
574 inline Reference
< interface_type
> & SAL_CALL
operator = ( interface_type
* pInterface
);
575 /** Assignment operator: Acquires given interface reference and sets reference.
576 An interface already set will be released.
578 @param rRef an interface reference
579 @return this reference
581 inline Reference
< interface_type
> & SAL_CALL
operator = ( const Reference
< interface_type
> & rRef
);
582 #if defined LIBO_INTERNAL_ONLY
583 /** Assignment move operator: Acquires given interface reference and sets reference.
584 An interface already set will be released.
586 @param rRef an interface reference
587 @return this reference
589 inline Reference
< interface_type
> & SAL_CALL
operator = ( Reference
< interface_type
> && rRef
);
591 /** Queries given interface reference for type interface_type.
593 @param rRef interface reference
594 @return interface reference of demanded type (may be null)
596 SAL_WARN_UNUSED_RESULT
inline static Reference
< interface_type
> SAL_CALL
query( const BaseReference
& rRef
);
597 /** Queries given interface for type interface_type.
599 @param pInterface interface pointer
600 @return interface reference of demanded type (may be null)
602 SAL_WARN_UNUSED_RESULT
inline static Reference
< interface_type
> SAL_CALL
query( XInterface
* pInterface
);
612 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */