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 
20 /*
21  * This file is part of LibreOffice published API.
22  */
23 #ifndef INCLUDED_COM_SUN_STAR_UNO_REFERENCE_H
24 #define INCLUDED_COM_SUN_STAR_UNO_REFERENCE_H
25 
26 #include "sal/config.h"
27 
28 #include <cassert>
29 #include <cstddef>
30 
31 #if defined LIBO_INTERNAL_ONLY
32 #include <type_traits>
33 #endif
34 
35 #include "rtl/alloc.h"
36 
37 namespace com
38 {
39 namespace sun
40 {
41 namespace star
42 {
43 namespace uno
44 {
45 
46 class RuntimeException;
47 class XInterface;
48 class Type;
49 class Any;
50 
51 /** Enum defining UNO_REF_NO_ACQUIRE for setting reference without acquiring a given interface.
52     Deprecated, please use SAL_NO_ACQUIRE.
53     @deprecated
54 */
55 enum UnoReference_NoAcquire
56 {
57     /** This enum value can be used for creating a reference granting a given interface,
58         i.e. transferring ownership to it.
59     */
60     UNO_REF_NO_ACQUIRE
61 };
62 
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 ==, =!.
65 */
66 class BaseReference
67 {
68 protected:
69     /** the interface pointer
70     */
71     XInterface * _pInterface;
72 
73     /** Queries given interface for type rType.
74 
75         @param pInterface interface pointer
76         @param rType interface type
77         @return interface of demanded type (may be null)
78     */
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.
82 
83         @param pInterface interface pointer
84         @param rType interface type
85         @return interface of demanded type
86     */
87     inline static XInterface * SAL_CALL iquery_throw( XInterface * pInterface, const Type & rType );
88 
89 public:
90     /** Gets interface pointer. This call does not acquire the interface.
91 
92         @return UNacquired interface pointer
93     */
get()94     XInterface * SAL_CALL get() const
95         { return _pInterface; }
96 
97     /** Checks if reference is null.
98 
99         @return true if reference acquires an interface, i.e. true if it is not null
100     */
is()101     bool SAL_CALL is() const
102         { return (NULL != _pInterface); }
103 
104 #if defined LIBO_INTERNAL_ONLY
105     /** Checks if reference is null.
106 
107         @return true if reference acquires an interface, i.e. true if it is not null
108     */
109     explicit operator bool() const
110         { return is(); }
111 #endif
112 
113     /** Equality operator: compares two interfaces
114         Checks if both references are null or refer to the same object.
115 
116         @param pInterface another interface
117         @return true if both references are null or refer to the same object, false otherwise
118     */
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.
122 
123         @param pInterface another interface
124         @return false if both references are null or refer to the same object, true otherwise
125     */
126     inline bool SAL_CALL operator != ( XInterface * pInterface ) const;
127 
128     /** Equality operator: compares two interfaces
129         Checks if both references are null or refer to the same object.
130 
131         @param rRef another reference
132         @return true if both references are null or refer to the same object, false otherwise
133     */
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.
137 
138         @param rRef another reference
139         @return false if both references are null or refer to the same object, true otherwise
140     */
141     inline bool SAL_CALL operator != ( const BaseReference & rRef ) const;
142 
143     /** Needed by some STL containers.
144 
145         @param rRef another reference
146         @return true, if this reference is less than rRef
147     */
148     inline bool SAL_CALL operator < ( const BaseReference & rRef ) const;
149 };
150 
151 /** Enum defining UNO_QUERY for implicit interface query.
152 */
153 enum UnoReference_Query
154 {
155     /** This enum value can be used for implicit interface query.
156     */
157     UNO_QUERY
158 };
159 /** Enum defining UNO_QUERY_THROW for implicit interface query.
160     If the demanded interface is unavailable, then a RuntimeException is thrown.
161 */
162 enum UnoReference_QueryThrow
163 {
164     /** This enum value can be used for implicit interface query.
165     */
166     UNO_QUERY_THROW
167 };
168 /** Enum defining UNO_SET_THROW for throwing if attempts are made to assign a null
169     interface
170 
171     @since UDK 3.2.8
172 */
173 enum UnoReference_SetThrow
174 {
175     UNO_SET_THROW
176 };
177 
178 /** Template reference class for interface type derived from BaseReference.
179     A special constructor given the UNO_QUERY identifier queries interfaces
180     for reference type.
181 */
182 template< class interface_type >
183 class SAL_DLLPUBLIC_RTTI Reference : public BaseReference
184 {
185     /** Queries given interface for type interface_type.
186 
187         @param pInterface interface pointer
188         @return interface of demanded type (may be null)
189     */
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.
193 
194         @param pInterface interface pointer
195         @return interface of demanded type
196     */
197     inline static XInterface * SAL_CALL iquery_throw( XInterface * pInterface );
198     /** Returns the given interface if it is not <NULL/>, throws a RuntimeException otherwise.
199 
200         @param pInterface interface pointer
201         @return pInterface
202     */
203     inline static interface_type * SAL_CALL iset_throw( interface_type * pInterface );
204 
205     /** Cast from an "interface pointer" (e.g., BaseReference::_pInterface) to a
206         pointer to this interface_type.
207 
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.
215     */
castFromXInterface(XInterface * p)216     static interface_type * castFromXInterface(XInterface * p) {
217         return static_cast< interface_type * >(static_cast< void * >(p));
218     }
219 
220     /** Cast from a pointer to this interface_type to an "interface pointer"
221         (e.g., BaseReference::_pInterface).
222 
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.
230     */
castToXInterface(interface_type * p)231     static XInterface * castToXInterface(interface_type * p) {
232         return static_cast< XInterface * >(static_cast< void * >(p));
233     }
234 
235 public:
236     /// @cond INTERNAL
237     // these are here to force memory de/allocation to sal lib.
new(::size_t nSize)238     static void * SAL_CALL operator new ( ::size_t nSize )
239         { return ::rtl_allocateMemory( nSize ); }
delete(void * pMem)240     static void SAL_CALL operator delete ( void * pMem )
241         { ::rtl_freeMemory( pMem ); }
new(::size_t,void * pMem)242     static void * SAL_CALL operator new ( ::size_t, void * pMem )
243         { return pMem; }
delete(void *,void *)244     static void SAL_CALL operator delete ( void *, void * )
245         {}
246     /// @endcond
247 
248     /** Destructor: Releases interface if set.
249     */
250     inline ~Reference() COVERITY_NOEXCEPT_FALSE;
251 
252     /** Default Constructor: Sets null reference.
253     */
254     inline Reference();
255 
256     /** Copy constructor: Copies interface reference.
257 
258         @param rRef another reference
259     */
260     inline Reference( const Reference< interface_type > & rRef );
261 
262 #if defined LIBO_INTERNAL_ONLY
263     /** Move constructor
264 
265         @param rRef another reference
266     */
267     inline Reference( Reference< interface_type > && rRef ) noexcept;
268 
269     /** Up-casting conversion constructor: Copies interface reference.
270 
271         Does not work for up-casts to ambiguous bases.  For the special case of
272         up-casting to Reference< XInterface >, see the corresponding conversion
273         operator.
274 
275         @param rRef another reference
276     */
277     template< class derived_type >
278     inline Reference(
279         const Reference< derived_type > & rRef,
280         std::enable_if_t<
281             std::is_base_of_v<interface_type, derived_type>
282             && !std::is_same_v<interface_type, XInterface>, void *> = nullptr);
283 #endif
284 
285     /** Constructor: Sets given interface pointer.
286 
287         @param pInterface an interface pointer
288     */
289     inline Reference( interface_type * pInterface );
290 
291     /** Constructor: Sets given interface pointer without acquiring it.
292 
293         @param pInterface another reference
294         @param dummy SAL_NO_ACQUIRE to force obvious distinction to other constructors
295     */
296     inline Reference( interface_type * pInterface, __sal_NoAcquire dummy);
297     /** Constructor: Sets given interface pointer without acquiring it.
298         Deprecated, please use SAL_NO_ACQUIRE version.
299 
300         @deprecated
301         @param pInterface another reference
302         @param dummy UNO_REF_NO_ACQUIRE to force obvious distinction to other constructors
303     */
304     inline SAL_DEPRECATED("use SAL_NO_ACQUIRE version") Reference( interface_type * pInterface, UnoReference_NoAcquire dummy );
305 
306     /** Constructor: Queries given interface for reference interface type (interface_type).
307 
308         @param rRef another reference
309         @param dummy UNO_QUERY to force obvious distinction to other constructors
310     */
311     inline Reference( const BaseReference & rRef, UnoReference_Query dummy );
312     /** Constructor: Queries given interface for reference interface type (interface_type).
313 
314         @param pInterface an interface pointer
315         @param dummy UNO_QUERY to force obvious distinction to other constructors
316     */
317     inline Reference( XInterface * pInterface, UnoReference_Query dummy);
318     /** Constructor: Queries given any for reference interface type (interface_type).
319 
320         @param rAny an any
321         @param dummy UNO_QUERY to force obvious distinction to other constructors
322     */
323     inline Reference( const Any & rAny, UnoReference_Query dummy);
324     /** Constructor: Queries given interface for reference interface type (interface_type).
325         Throws a RuntimeException if the demanded interface cannot be queried.
326 
327         @param rRef another reference
328         @param dummy UNO_QUERY_THROW to force obvious distinction
329                      to other constructors
330     */
331     inline Reference( const BaseReference & rRef, UnoReference_QueryThrow dummy );
332 #ifdef LIBO_INTERNAL_ONLY
333     /**
334         Prevent code from calling the QUERY_THROW constructor, when they meant to use the SET_THROW constructor.
335     */
336     Reference( const Reference< interface_type > & rRef, UnoReference_QueryThrow dummy ) = delete;
337 #endif
338     /** Constructor: Queries given interface for reference interface type (interface_type).
339         Throws a RuntimeException if the demanded interface cannot be queried.
340 
341         @param pInterface an interface pointer
342         @param dummy UNO_QUERY_THROW to force obvious distinction
343                      to other constructors
344     */
345     inline Reference( XInterface * pInterface, UnoReference_QueryThrow dummy );
346     /** Constructor: Queries given any for reference interface type (interface_type).
347         Throws a RuntimeException if the demanded interface cannot be queried.
348 
349         @param rAny an any
350         @param dummy UNO_QUERY_THROW to force obvious distinction
351                      to other constructors
352     */
353     inline Reference( const Any & rAny, UnoReference_QueryThrow dummy );
354     /** Constructor: assigns from the given interface of the same type. Throws a RuntimeException
355         if the source interface is NULL.
356 
357         @param rRef another interface reference of the same type
358         @param dummy UNO_SET_THROW to distinguish from default copy constructor
359 
360         @since UDK 3.2.8
361     */
362     inline Reference( const Reference< interface_type > & rRef, UnoReference_SetThrow dummy );
363     /** Constructor: assigns from the given interface of the same type. Throws a RuntimeException
364         if the source interface is NULL.
365 
366         @param pInterface an interface pointer
367         @param dummy UNO_SET_THROW to distinguish from default assignment constructor
368 
369         @since UDK 3.2.8
370     */
371     inline Reference( interface_type * pInterface, UnoReference_SetThrow dummy );
372 
373     /** Cast operator to Reference< XInterface >: Reference objects are binary compatible and
374         any interface must be derived from com.sun.star.uno.XInterface.
375         This a useful direct cast possibility.
376     */
377     SAL_CALL operator const Reference< XInterface > & () const
378         { return * reinterpret_cast< const Reference< XInterface > * >( this ); }
379 
380     /** Dereference operator: Used to call interface methods.
381 
382         @return UNacquired interface pointer
383     */
384     interface_type * SAL_CALL operator -> () const {
385         assert(_pInterface != NULL);
386         return castFromXInterface(_pInterface);
387     }
388 
389     /** Indirection operator.
390 
391         @since LibreOffice 6.3
392         @return UNacquired interface reference
393     */
394     interface_type & SAL_CALL operator * () const {
395         assert(_pInterface != NULL);
396         return *castFromXInterface(_pInterface);
397     }
398 
399     /** Gets interface pointer. This call does not acquire the interface.
400 
401         @return UNacquired interface pointer
402     */
get()403     interface_type * SAL_CALL get() const
404         { return castFromXInterface(_pInterface); }
405 
406     /** Clears reference, i.e. releases interface. Reference is null after clear() call.
407     */
408     inline void SAL_CALL clear();
409 
410     /** Sets the given interface. An interface already set will be released.
411 
412         @param rRef another reference
413         @return true, if non-null interface was set
414     */
415     inline bool SAL_CALL set( const Reference< interface_type > & rRef );
416     /** Sets the given interface. An interface already set will be released.
417 
418         @param pInterface another interface
419         @return true, if non-null interface was set
420     */
421     inline bool SAL_CALL set( interface_type * pInterface );
422 
423     /** Sets interface pointer without acquiring it. An interface already set will be released.
424 
425         @param pInterface an interface pointer
426         @param dummy SAL_NO_ACQUIRE to force obvious distinction to set methods
427         @return true, if non-null interface was set
428     */
429     inline bool SAL_CALL set( interface_type * pInterface, __sal_NoAcquire dummy);
430     /** Sets interface pointer without acquiring it. An interface already set will be released.
431         Deprecated, please use SAL_NO_ACQUIRE version.
432 
433         @deprecated
434         @param pInterface an interface pointer
435         @param dummy UNO_REF_NO_ACQUIRE to force obvious distinction to set methods
436         @return true, if non-null interface was set
437     */
438     inline SAL_DEPRECATED("use SAL_NO_ACQUIRE version") bool SAL_CALL set( interface_type * pInterface, UnoReference_NoAcquire dummy);
439 
440     /** Queries given interface for reference interface type (interface_type) and sets it.
441         An interface already set will be released.
442 
443         @param pInterface an interface pointer
444         @param dummy UNO_QUERY to force obvious distinction to set methods
445         @return true, if non-null interface was set
446     */
447     inline bool SAL_CALL set( XInterface * pInterface, UnoReference_Query dummy );
448     /** Queries given interface for reference interface type (interface_type) and sets it.
449         An interface already set will be released.
450 
451         @param rRef another reference
452         @param dummy UNO_QUERY to force obvious distinction to set methods
453         @return true, if non-null interface was set
454     */
455     inline bool SAL_CALL set( const BaseReference & rRef, UnoReference_Query dummy);
456 
457     /** Queries given any for reference interface type (interface_type)
458         and sets it.  An interface already set will be released.
459 
460         @param rAny
461                an Any containing an interface
462         @param dummy
463                UNO_QUERY to force obvious distinction
464                to set methods
465         @return
466                 true, if non-null interface was set
467     */
468     inline bool set( Any const & rAny, UnoReference_Query dummy );
469 
470     /** Queries given interface for reference interface type (interface_type) and sets it.
471         An interface already set will be released.
472         Throws a RuntimeException if the demanded interface cannot be set.
473 
474         @param pInterface an interface pointer
475         @param dummy UNO_QUERY_THROW to force obvious distinction
476                      to set methods
477     */
478     inline void SAL_CALL set( XInterface * pInterface, UnoReference_QueryThrow dummy );
479     /** Queries given interface for reference interface type (interface_type) and sets it.
480         An interface already set will be released.
481         Throws a RuntimeException if the demanded interface cannot be set.
482 
483         @param rRef another reference
484         @param dummy UNO_QUERY_THROW to force obvious distinction
485                to set methods
486     */
487     inline void SAL_CALL set( const BaseReference & rRef, UnoReference_QueryThrow dummy );
488 #ifdef LIBO_INTERNAL_ONLY
489     /**
490         Prevent code from calling the QUERY_THROW version, when they meant to use the SET_THROW version.
491     */
492     void set( const Reference< interface_type > & rRef, UnoReference_QueryThrow dummy ) = delete;
493 #endif
494 
495     /** Queries given any for reference interface type (interface_type) and
496         sets it.  An interface already set will be released.
497         Throws a RuntimeException if the demanded interface cannot be set.
498 
499         @param rAny
500                an Any containing an interface
501         @param dummy
502                UNO_QUERY_THROW to force obvious distinction to set methods
503     */
504     inline void set( Any const & rAny, UnoReference_QueryThrow dummy);
505     /** sets the given interface
506         An interface already set will be released.
507         Throws a RuntimeException if the source interface is @b NULL.
508 
509         @param pInterface an interface pointer
510         @param dummy UNO_SET_THROW to force obvious distinction to other set methods
511 
512         @since UDK 3.2.8
513     */
514     inline void SAL_CALL set( interface_type * pInterface, UnoReference_SetThrow dummy);
515     /** sets the given interface
516         An interface already set will be released.
517         Throws a RuntimeException if the source interface is @b NULL.
518 
519         @param rRef an interface reference
520         @param dummy UNO_SET_THROW to force obvious distinction to other set methods
521 
522         @since UDK 3.2.8
523     */
524     inline void SAL_CALL set( const Reference< interface_type > & rRef, UnoReference_SetThrow dummy);
525 
526 
527     /** Assignment operator: Acquires given interface pointer and sets reference.
528         An interface already set will be released.
529 
530         @param pInterface an interface pointer
531         @return this reference
532     */
533     inline Reference< interface_type > & SAL_CALL operator = ( interface_type * pInterface );
534     /** Assignment operator: Acquires given interface reference and sets reference.
535         An interface already set will be released.
536 
537         @param rRef an interface reference
538         @return this reference
539     */
540     inline Reference< interface_type > & SAL_CALL operator = ( const Reference< interface_type > & rRef );
541 #if defined LIBO_INTERNAL_ONLY
542     /** Assignment move operator: Acquires given interface reference and sets reference.
543         An interface already set will be released.
544 
545         @param rRef an interface reference
546         @return this reference
547     */
548     inline Reference< interface_type > & SAL_CALL operator = ( Reference< interface_type > && rRef ) noexcept;
549 #endif
550     /** Queries given interface reference for type interface_type.
551 
552         @param rRef interface reference
553         @return interface reference of demanded type (may be null)
554     */
555     SAL_WARN_UNUSED_RESULT inline static Reference< interface_type > SAL_CALL query( const BaseReference & rRef );
556     /** Queries given interface for type interface_type.
557 
558         @param pInterface interface pointer
559         @return interface reference of demanded type (may be null)
560     */
561     SAL_WARN_UNUSED_RESULT inline static Reference< interface_type > SAL_CALL query( XInterface * pInterface );
562 };
563 
564 }
565 }
566 }
567 }
568 
569 #endif
570 
571 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
572