xref: /core/include/com/sun/star/uno/Reference.h (revision 06ec8a95)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 #ifndef INCLUDED_COM_SUN_STAR_UNO_REFERENCE_H
20 #define INCLUDED_COM_SUN_STAR_UNO_REFERENCE_H
21 
22 #include "sal/config.h"
23 
24 #include <cassert>
25 #include <cstddef>
26 
27 #include "rtl/alloc.h"
28 
29 namespace com
30 {
31 namespace sun
32 {
33 namespace star
34 {
35 namespace uno
36 {
37 
38 class RuntimeException;
39 class XInterface;
40 class Type;
41 class Any;
42 
43 /** Enum defining UNO_REF_NO_ACQUIRE for setting reference without acquiring a given interface.
44     Deprecated, please use SAL_NO_ACQUIRE.
45     @deprecated
46 */
47 enum UnoReference_NoAcquire
48 {
49     /** This enum value can be used for creating a reference granting a given interface,
50         i.e. transferring ownership to it.
51     */
52     UNO_REF_NO_ACQUIRE
53 };
54 
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 ==, =!.
57 */
58 class BaseReference
59 {
60 protected:
61     /** the interface pointer
62     */
63     XInterface * _pInterface;
64 
65     /** Queries given interface for type rType.
66 
67         @param pInterface interface pointer
68         @param rType interface type
69         @return interface of demanded type (may be null)
70     */
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.
74 
75         @param pInterface interface pointer
76         @param rType interface type
77         @return interface of demanded type
78     */
79     inline static XInterface * SAL_CALL iquery_throw( XInterface * pInterface, const Type & rType );
80 
81 public:
82     /** Gets interface pointer. This call does not acquire the interface.
83 
84         @return UNacquired interface pointer
85     */
86     XInterface * SAL_CALL get() const
87         { return _pInterface; }
88 
89     /** Checks if reference is null.
90 
91         @return true if reference acquires an interface, i.e. true if it is not null
92     */
93     bool SAL_CALL is() const
94         { return (NULL != _pInterface); }
95 
96 #if defined LIBO_INTERNAL_ONLY
97     /** Checks if reference is null.
98 
99         @return true if reference acquires an interface, i.e. true if it is not null
100     */
101     explicit operator bool() const
102         { return is(); }
103 #endif
104 
105     /** Equality operator: compares two interfaces
106         Checks if both references are null or refer to the same object.
107 
108         @param pInterface another interface
109         @return true if both references are null or refer to the same object, false otherwise
110     */
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.
114 
115         @param pInterface another interface
116         @return false if both references are null or refer to the same object, true otherwise
117     */
118     inline bool SAL_CALL operator != ( XInterface * pInterface ) const;
119 
120     /** Equality operator: compares two interfaces
121         Checks if both references are null or refer to the same object.
122 
123         @param rRef another reference
124         @return true if both references are null or refer to the same object, false otherwise
125     */
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.
129 
130         @param rRef another reference
131         @return false if both references are null or refer to the same object, true otherwise
132     */
133     inline bool SAL_CALL operator != ( const BaseReference & rRef ) const;
134 
135     /** Needed by some STL containers.
136 
137         @param rRef another reference
138         @return true, if this reference is less than rRef
139     */
140     inline bool SAL_CALL operator < ( const BaseReference & rRef ) const;
141 };
142 
143 /** Enum defining UNO_QUERY for implicit interface query.
144 */
145 enum UnoReference_Query
146 {
147     /** This enum value can be used for implicit interface query.
148     */
149     UNO_QUERY
150 };
151 /** Enum defining UNO_QUERY_THROW for implicit interface query.
152     If the demanded interface is unavailable, then a RuntimeException is thrown.
153 */
154 enum UnoReference_QueryThrow
155 {
156     /** This enum value can be used for implicit interface query.
157     */
158     UNO_QUERY_THROW
159 };
160 /** Enum defining UNO_SET_THROW for throwing if attempts are made to assign a null
161     interface
162 
163     @since UDK 3.2.8
164 */
165 enum UnoReference_SetThrow
166 {
167     UNO_SET_THROW
168 };
169 
170 /// @cond INTERNAL
171 namespace detail {
172 
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):
183 
184 template< typename T1, typename T2 > struct UpCast {
185 private:
186     template< bool, typename U1, typename > struct C
187     { typedef U1 t; };
188 
189     template< typename U1, typename U2 > struct C< false, U1, U2 >
190     { typedef U2 t; };
191 
192     struct S { char c[2]; };
193 
194 #if defined _MSC_VER && _MSC_VER < 1800
195     static char f(T2 *, long);
196     static S f(T1 * const &, int);
197 #else
198     template< typename U > static char f(T2 *, U);
199     static S f(T1 *, int);
200 #endif
201 
202     struct H {
203         H(); // avoid C2514 "class has no constructors" from MSVC
204 #if defined _MSC_VER && _MSC_VER < 1800
205         operator T1 * const & () const;
206 #else
207         operator T1 * () const;
208 #endif
209         operator T2 * ();
210     };
211 
212 public:
213     typedef typename C< sizeof (f(H(), 0)) == 1, void *, void >::t t;
214 };
215 
216 template< typename T2 > struct UpCast< XInterface, T2 > {};
217 
218 }
219 /// @endcond
220 
221 /** Template reference class for interface type derived from BaseReference.
222     A special constructor given the UNO_QUERY identifier queries interfaces
223     for reference type.
224 */
225 template< class interface_type >
226 class SAL_DLLPUBLIC_RTTI Reference : public BaseReference
227 {
228     /** Queries given interface for type interface_type.
229 
230         @param pInterface interface pointer
231         @return interface of demanded type (may be null)
232     */
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.
236 
237         @param pInterface interface pointer
238         @return interface of demanded type
239     */
240     inline static XInterface * SAL_CALL iquery_throw( XInterface * pInterface );
241     /** Returns the given interface if it is not <NULL/>, throws a RuntimeException otherwise.
242 
243         @param pInterface interface pointer
244         @return pInterface
245     */
246     inline static interface_type * SAL_CALL iset_throw( interface_type * pInterface );
247 
248     /** Cast from an "interface pointer" (e.g., BaseReference::_pInterface) to a
249         pointer to this interface_type.
250 
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.
258     */
259     static interface_type * castFromXInterface(XInterface * p) {
260         return static_cast< interface_type * >(static_cast< void * >(p));
261     }
262 
263     /** Cast from a pointer to this interface_type to an "interface pointer"
264         (e.g., BaseReference::_pInterface).
265 
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.
273     */
274     static XInterface * castToXInterface(interface_type * p) {
275         return static_cast< XInterface * >(static_cast< void * >(p));
276     }
277 
278 public:
279     /// @cond INTERNAL
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 )
286         { return pMem; }
287     static void SAL_CALL operator delete ( void *, void * )
288         {}
289     /// @endcond
290 
291     /** Destructor: Releases interface if set.
292     */
293     inline ~Reference() COVERITY_NOEXCEPT_FALSE;
294 
295     /** Default Constructor: Sets null reference.
296     */
297     inline Reference();
298 
299     /** Copy constructor: Copies interface reference.
300 
301         @param rRef another reference
302     */
303     inline Reference( const Reference< interface_type > & rRef );
304 
305 #if defined LIBO_INTERNAL_ONLY
306     /** Move constructor
307 
308         @param rRef another reference
309     */
310     inline Reference( Reference< interface_type > && rRef );
311 #endif
312 
313     /** Up-casting conversion constructor: Copies interface reference.
314 
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
317         operator.
318 
319         @param rRef another reference
320     */
321     template< class derived_type >
322     inline Reference(
323         const Reference< derived_type > & rRef,
324         typename detail::UpCast< interface_type, derived_type >::t = 0 );
325 
326     /** Constructor: Sets given interface pointer.
327 
328         @param pInterface an interface pointer
329     */
330     inline Reference( interface_type * pInterface );
331 
332     /** Constructor: Sets given interface pointer without acquiring it.
333 
334         @param pInterface another reference
335         @param dummy SAL_NO_ACQUIRE to force obvious distinction to other constructors
336     */
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.
340 
341         @deprecated
342         @param pInterface another reference
343         @param dummy UNO_REF_NO_ACQUIRE to force obvious distinction to other constructors
344     */
345     inline SAL_DEPRECATED("use SAL_NO_ACQUIRE version") Reference( interface_type * pInterface, UnoReference_NoAcquire dummy );
346 
347     /** Constructor: Queries given interface for reference interface type (interface_type).
348 
349         @param rRef another reference
350         @param dummy UNO_QUERY to force obvious distinction to other constructors
351     */
352     inline Reference( const BaseReference & rRef, UnoReference_Query dummy );
353     /** Constructor: Queries given interface for reference interface type (interface_type).
354 
355         @param pInterface an interface pointer
356         @param dummy UNO_QUERY to force obvious distinction to other constructors
357     */
358     inline Reference( XInterface * pInterface, UnoReference_Query dummy);
359     /** Constructor: Queries given any for reference interface type (interface_type).
360 
361         @param rAny an any
362         @param dummy UNO_QUERY to force obvious distinction to other constructors
363     */
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.
367 
368         @param rRef another reference
369         @param dummy UNO_QUERY_THROW to force obvious distinction
370                      to other constructors
371     */
372     inline Reference( const BaseReference & rRef, UnoReference_QueryThrow dummy );
373     /** Constructor: Queries given interface for reference interface type (interface_type).
374         Throws a RuntimeException if the demanded interface cannot be queried.
375 
376         @param pInterface an interface pointer
377         @param dummy UNO_QUERY_THROW to force obvious distinction
378                      to other constructors
379     */
380     inline Reference( XInterface * pInterface, UnoReference_QueryThrow dummy );
381     /** Constructor: Queries given any for reference interface type (interface_type).
382         Throws a RuntimeException if the demanded interface cannot be queried.
383 
384         @param rAny an any
385         @param dummy UNO_QUERY_THROW to force obvious distinction
386                      to other constructors
387     */
388     inline Reference( const Any & rAny, UnoReference_QueryThrow dummy );
389     /** Constructor: assigns from the given interface of the same type. Throws a RuntimeException
390         if the source interface is NULL.
391 
392         @param rRef another interface reference of the same type
393         @param dummy UNO_SET_THROW to distinguish from default copy constructor
394 
395         @since UDK 3.2.8
396     */
397     inline Reference( const Reference< interface_type > & rRef, UnoReference_SetThrow dummy );
398     /** Constructor: assigns from the given interface of the same type. Throws a RuntimeException
399         if the source interface is NULL.
400 
401         @param pInterface an interface pointer
402         @param dummy UNO_SET_THROW to distinguish from default assignment constructor
403 
404         @since UDK 3.2.8
405     */
406     inline Reference( interface_type * pInterface, UnoReference_SetThrow dummy );
407 
408     /** Cast operator to Reference< XInterface >: Reference objects are binary compatible and
409         any interface must be derived from com.sun.star.uno.XInterface.
410         This a useful direct cast possibility.
411     */
412     SAL_CALL operator const Reference< XInterface > & () const
413         { return * reinterpret_cast< const Reference< XInterface > * >( this ); }
414 
415     /** Dereference operator: Used to call interface methods.
416 
417         @return UNacquired interface pointer
418     */
419     interface_type * SAL_CALL operator -> () const {
420         assert(_pInterface != NULL);
421         return castFromXInterface(_pInterface);
422     }
423 
424     /** Indirection operator.
425 
426         @since LibreOffice 6.3
427         @return UNacquired interface reference
428     */
429     interface_type & SAL_CALL operator * () const {
430         assert(_pInterface != NULL);
431         return *castFromXInterface(_pInterface);
432     }
433 
434     /** Gets interface pointer. This call does not acquire the interface.
435 
436         @return UNacquired interface pointer
437     */
438     interface_type * SAL_CALL get() const
439         { return castFromXInterface(_pInterface); }
440 
441     /** Clears reference, i.e. releases interface. Reference is null after clear() call.
442     */
443     inline void SAL_CALL clear();
444 
445     /** Sets the given interface. An interface already set will be released.
446 
447         @param rRef another reference
448         @return true, if non-null interface was set
449     */
450     inline bool SAL_CALL set( const Reference< interface_type > & rRef );
451     /** Sets the given interface. An interface already set will be released.
452 
453         @param pInterface another interface
454         @return true, if non-null interface was set
455     */
456     inline bool SAL_CALL set( interface_type * pInterface );
457 
458     /** Sets interface pointer without acquiring it. An interface already set will be released.
459 
460         @param pInterface an interface pointer
461         @param dummy SAL_NO_ACQUIRE to force obvious distinction to set methods
462         @return true, if non-null interface was set
463     */
464     inline bool SAL_CALL set( interface_type * pInterface, __sal_NoAcquire dummy);
465     /** Sets interface pointer without acquiring it. An interface already set will be released.
466         Deprecated, please use SAL_NO_ACQUIRE version.
467 
468         @deprecated
469         @param pInterface an interface pointer
470         @param dummy UNO_REF_NO_ACQUIRE to force obvious distinction to set methods
471         @return true, if non-null interface was set
472     */
473     inline SAL_DEPRECATED("use SAL_NO_ACQUIRE version") bool SAL_CALL set( interface_type * pInterface, UnoReference_NoAcquire dummy);
474 
475     /** Queries given interface for reference interface type (interface_type) and sets it.
476         An interface already set will be released.
477 
478         @param pInterface an interface pointer
479         @param dummy UNO_QUERY to force obvious distinction to set methods
480         @return true, if non-null interface was set
481     */
482     inline bool SAL_CALL set( XInterface * pInterface, UnoReference_Query dummy );
483     /** Queries given interface for reference interface type (interface_type) and sets it.
484         An interface already set will be released.
485 
486         @param rRef another reference
487         @param dummy UNO_QUERY to force obvious distinction to set methods
488         @return true, if non-null interface was set
489     */
490     inline bool SAL_CALL set( const BaseReference & rRef, UnoReference_Query dummy);
491 
492     /** Queries given any for reference interface type (interface_type)
493         and sets it.  An interface already set will be released.
494 
495         @param rAny
496                an Any containing an interface
497         @param dummy
498                UNO_QUERY to force obvious distinction
499                to set methods
500         @return
501                 true, if non-null interface was set
502     */
503     inline bool set( Any const & rAny, UnoReference_Query dummy );
504 
505     /** Queries given interface for reference interface type (interface_type) and sets it.
506         An interface already set will be released.
507         Throws a RuntimeException if the demanded interface cannot be set.
508 
509         @param pInterface an interface pointer
510         @param dummy UNO_QUERY_THROW to force obvious distinction
511                      to set methods
512     */
513     inline void SAL_CALL set( XInterface * pInterface, UnoReference_QueryThrow dummy );
514     /** Queries given interface for reference interface type (interface_type) and sets it.
515         An interface already set will be released.
516         Throws a RuntimeException if the demanded interface cannot be set.
517 
518         @param rRef another reference
519         @param dummy UNO_QUERY_THROW to force obvious distinction
520                to set methods
521     */
522     inline void SAL_CALL set( const BaseReference & rRef, UnoReference_QueryThrow dummy );
523 
524     /** Queries given any for reference interface type (interface_type) and
525         sets it.  An interface already set will be released.
526         Throws a RuntimeException if the demanded interface cannot be set.
527 
528         @param rAny
529                an Any containing an interface
530         @param dummy
531                UNO_QUERY_THROW to force obvious distinction to set methods
532     */
533     inline void set( Any const & rAny, UnoReference_QueryThrow dummy);
534     /** sets the given interface
535         An interface already set will be released.
536         Throws a RuntimeException if the source interface is @b NULL.
537 
538         @param pInterface an interface pointer
539         @param dummy UNO_SET_THROW to force obvious distinction to other set methods
540 
541         @since UDK 3.2.8
542     */
543     inline void SAL_CALL set( interface_type * pInterface, UnoReference_SetThrow dummy);
544     /** sets the given interface
545         An interface already set will be released.
546         Throws a RuntimeException if the source interface is @b NULL.
547 
548         @param rRef an interface reference
549         @param dummy UNO_SET_THROW to force obvious distinction to other set methods
550 
551         @since UDK 3.2.8
552     */
553     inline void SAL_CALL set( const Reference< interface_type > & rRef, UnoReference_SetThrow dummy);
554 
555 
556     /** Assignment operator: Acquires given interface pointer and sets reference.
557         An interface already set will be released.
558 
559         @param pInterface an interface pointer
560         @return this reference
561     */
562     inline Reference< interface_type > & SAL_CALL operator = ( interface_type * pInterface );
563     /** Assignment operator: Acquires given interface reference and sets reference.
564         An interface already set will be released.
565 
566         @param rRef an interface reference
567         @return this reference
568     */
569     inline Reference< interface_type > & SAL_CALL operator = ( const Reference< interface_type > & rRef );
570 #if defined LIBO_INTERNAL_ONLY
571     /** Assignment move operator: Acquires given interface reference and sets reference.
572         An interface already set will be released.
573 
574         @param rRef an interface reference
575         @return this reference
576     */
577     inline Reference< interface_type > & SAL_CALL operator = ( Reference< interface_type > && rRef );
578 #endif
579     /** Queries given interface reference for type interface_type.
580 
581         @param rRef interface reference
582         @return interface reference of demanded type (may be null)
583     */
584     SAL_WARN_UNUSED_RESULT inline static Reference< interface_type > SAL_CALL query( const BaseReference & rRef );
585     /** Queries given interface for type interface_type.
586 
587         @param pInterface interface pointer
588         @return interface reference of demanded type (may be null)
589     */
590     SAL_WARN_UNUSED_RESULT inline static Reference< interface_type > SAL_CALL query( XInterface * pInterface );
591 };
592 
593 }
594 }
595 }
596 }
597 
598 #endif
599 
600 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
601