Line data Source code
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 :
26 : #include <rtl/alloc.h>
27 :
28 : namespace com
29 : {
30 : namespace sun
31 : {
32 : namespace star
33 : {
34 : namespace uno
35 : {
36 :
37 : class RuntimeException;
38 : class XInterface;
39 : class Type;
40 : class Any;
41 :
42 : /** Enum defining UNO_REF_NO_ACQUIRE for setting reference without acquiring a given interface.
43 : Deprecated, please use SAL_NO_ACQUIRE.
44 : @deprecated
45 : */
46 : enum UnoReference_NoAcquire
47 : {
48 : /** This enum value can be used for creating a reference granting a given interface,
49 : i.e. transferring ownership to it.
50 : */
51 : UNO_REF_NO_ACQUIRE
52 : };
53 :
54 : /** This base class serves as a base class for all template reference classes and
55 : has been introduced due to compiler problems with templated operators ==, =!.
56 : */
57 508202071 : class BaseReference
58 : {
59 : protected:
60 : /** the interface pointer
61 : */
62 : XInterface * _pInterface;
63 :
64 : /** Queries given interface for type rType.
65 :
66 : @param pInterface interface pointer
67 : @param rType interface type
68 : @return interface of demanded type (may be null)
69 : */
70 : inline static XInterface * SAL_CALL iquery( XInterface * pInterface, const Type & rType );
71 : /** Queries given interface for type rType.
72 : Throws a RuntimeException if the demanded interface cannot be queried.
73 :
74 : @param pInterface interface pointer
75 : @param rType interface type
76 : @return interface of demanded type
77 : */
78 : inline static XInterface * SAL_CALL iquery_throw( XInterface * pInterface, const Type & rType );
79 :
80 : public:
81 : /** Gets interface pointer. This call does not acquire the interface.
82 :
83 : @return UNacquired interface pointer
84 : */
85 59305870 : inline XInterface * SAL_CALL get() const
86 59305870 : { return _pInterface; }
87 :
88 : /** Checks if reference is null.
89 :
90 : @return true if reference acquires an interface, i.e. true if it is not null
91 : */
92 387036075 : inline bool SAL_CALL is() const
93 387036075 : { return (0 != _pInterface); }
94 :
95 : /** Equality operator: compares two interfaces
96 : Checks if both references are null or refer to the same object.
97 :
98 : @param pInterface another interface
99 : @return true if both references are null or refer to the same object, false otherwise
100 : */
101 : inline bool SAL_CALL operator == ( XInterface * pInterface ) const;
102 : /** Unequality operator: compares two interfaces
103 : Checks if both references are null or refer to the same object.
104 :
105 : @param pInterface another interface
106 : @return false if both references are null or refer to the same object, true otherwise
107 : */
108 : inline bool SAL_CALL operator != ( XInterface * pInterface ) const;
109 :
110 : /** Equality operator: compares two interfaces
111 : Checks if both references are null or refer to the same object.
112 :
113 : @param rRef another reference
114 : @return true if both references are null or refer to the same object, false otherwise
115 : */
116 : inline bool SAL_CALL operator == ( const BaseReference & rRef ) const;
117 : /** Unequality operator: compares two interfaces
118 : Checks if both references are null or refer to the same object.
119 :
120 : @param rRef another reference
121 : @return false if both references are null or refer to the same object, true otherwise
122 : */
123 : inline bool SAL_CALL operator != ( const BaseReference & rRef ) const;
124 :
125 : /** Needed by some STL containers.
126 :
127 : @param rRef another reference
128 : @return true, if this reference is less than rRef
129 : */
130 : inline bool SAL_CALL operator < ( const BaseReference & rRef ) const;
131 : };
132 :
133 : /** Enum defining UNO_QUERY for implicit interface query.
134 : */
135 : enum UnoReference_Query
136 : {
137 : /** This enum value can be used for implicit interface query.
138 : */
139 : UNO_QUERY
140 : };
141 : /** Enum defining UNO_QUERY_THROW for implicit interface query.
142 : If the demanded interface is unavailable, then a RuntimeException is thrown.
143 : */
144 : enum UnoReference_QueryThrow
145 : {
146 : /** This enum value can be used for implicit interface query.
147 : */
148 : UNO_QUERY_THROW
149 : };
150 : /** Enum defining UNO_SET_THROW for throwing if attempts are made to assign a null
151 : interface
152 :
153 : @since UDK 3.2.8
154 : */
155 : enum UnoReference_SetThrow
156 : {
157 : UNO_SET_THROW
158 : };
159 :
160 : /// @cond INTERNAL
161 : namespace detail {
162 :
163 : // A mechanism to enable up-casts, used by the Reference conversion constructor,
164 : // but at the same time disable up-casts to XInterface, so that the conversion
165 : // operator for that special case is used in an expression like
166 : // Reference< XInterface >(x); heavily borrowed from boost::is_base_and_derived
167 : // (which manages to avoid compilation problems with ambiguous bases and cites
168 : // comp.lang.c++.moderated mail <http://groups.google.com/groups?
169 : // selm=df893da6.0301280859.522081f7%40posting.google.com> "SuperSubclass
170 : // (is_base_and_derived) complete implementation!" by Rani Sharoni and cites
171 : // Aleksey Gurtovoy for the workaround for MSVC), to avoid including Boost
172 : // headers in URE headers (could ultimately be based on C++11 std::is_base_of):
173 :
174 : template< typename T1, typename T2 > struct UpCast {
175 : private:
176 : template< bool, typename U1, typename > struct C
177 : { typedef U1 t; };
178 :
179 : template< typename U1, typename U2 > struct C< false, U1, U2 >
180 : { typedef U2 t; };
181 :
182 : struct S { char c[2]; };
183 :
184 : #if defined _MSC_VER
185 : static char f(T2 *, long);
186 : static S f(T1 * const &, int);
187 : #else
188 : template< typename U > static char f(T2 *, U);
189 : static S f(T1 *, int);
190 : #endif
191 :
192 : struct H {
193 : H(); // avoid C2514 "class has no constructors" from MSVC 2008
194 : #if defined _MSC_VER
195 : operator T1 * const & () const;
196 : #else
197 : operator T1 * () const;
198 : #endif
199 : operator T2 * ();
200 : };
201 :
202 : public:
203 : typedef typename C< sizeof (f(H(), 0)) == 1, void *, void >::t t;
204 : };
205 :
206 : template< typename T2 > struct UpCast< XInterface, T2 > {};
207 :
208 : }
209 : /// @endcond
210 :
211 : /** Template reference class for interface type derived from BaseReference.
212 : A special constructor given the UNO_QUERY identifier queries interfaces
213 : for reference type.
214 : */
215 : template< class interface_type >
216 : class Reference : public BaseReference
217 : {
218 : /** Queries given interface for type interface_type.
219 :
220 : @param pInterface interface pointer
221 : @return interface of demanded type (may be null)
222 : */
223 : inline static XInterface * SAL_CALL iquery( XInterface * pInterface );
224 : /** Queries given interface for type interface_type.
225 : Throws a RuntimeException if the demanded interface cannot be queried.
226 :
227 : @param pInterface interface pointer
228 : @return interface of demanded type
229 : */
230 : inline static XInterface * SAL_CALL iquery_throw( XInterface * pInterface );
231 : /** Returns the given interface if it is not <NULL/>, throws a RuntimeException otherwise.
232 :
233 : @param pInterface interface pointer
234 : @return pInterface
235 : */
236 : inline static interface_type * SAL_CALL iset_throw( interface_type * pInterface );
237 :
238 : /** Cast from an "interface pointer" (e.g., BaseReference::_pInterface) to a
239 : pointer to this interface_type.
240 :
241 : To work around ambiguities in the case of multiple-inheritance interface
242 : types (which inherit XInterface more than once), use reinterpret_cast
243 : (resp. a sequence of two static_casts, to avoid warnings about
244 : reinterpret_cast used between related classes) to switch from a pointer
245 : to XInterface to a pointer to this derived interface_type. In
246 : principle, this is not guaranteed to work. In practice, it seems to
247 : work on all supported platforms.
248 : */
249 462396856 : static inline interface_type * castFromXInterface(XInterface * p) {
250 462396856 : return static_cast< interface_type * >(static_cast< void * >(p));
251 : }
252 :
253 : /** Cast from a pointer to this interface_type to an "interface pointer"
254 : (e.g., BaseReference::_pInterface).
255 :
256 : To work around ambiguities in the case of multiple-inheritance interface
257 : types (which inherit XInterface more than once), use reinterpret_cast
258 : (resp. a sequence of two static_casts, to avoid warnings about
259 : reinterpret_cast used between related classes) to switch from a pointer
260 : to this derived interface_type to a pointer to XInterface. In
261 : principle, this is not guaranteed to work. In practice, it seems to
262 : work on all supported platforms.
263 : */
264 443733392 : static inline XInterface * castToXInterface(interface_type * p) {
265 443733392 : return static_cast< XInterface * >(static_cast< void * >(p));
266 : }
267 :
268 : public:
269 : /// @cond INTERNAL
270 : // these are here to force memory de/allocation to sal lib.
271 49823 : inline static void * SAL_CALL operator new ( ::size_t nSize )
272 49823 : { return ::rtl_allocateMemory( nSize ); }
273 49779 : inline static void SAL_CALL operator delete ( void * pMem )
274 49779 : { ::rtl_freeMemory( pMem ); }
275 0 : inline static void * SAL_CALL operator new ( ::size_t, void * pMem )
276 0 : { return pMem; }
277 0 : inline static void SAL_CALL operator delete ( void *, void * )
278 0 : {}
279 : /// @endcond
280 :
281 : /** Destructor: Releases interface if set.
282 : */
283 : inline ~Reference();
284 :
285 : /** Default Constructor: Sets null reference.
286 : */
287 : inline Reference();
288 :
289 : /** Copy constructor: Copies interface reference.
290 :
291 : @param rRef another reference
292 : */
293 : inline Reference( const Reference< interface_type > & rRef );
294 :
295 : /** Up-casting conversion constructor: Copies interface reference.
296 :
297 : Does not work for up-casts to ambiguous bases. For the special case of
298 : up-casting to Reference< XInterface >, see the corresponding conversion
299 : operator.
300 :
301 : @param rRef another reference
302 : */
303 : template< class derived_type >
304 : inline Reference(
305 : const Reference< derived_type > & rRef,
306 : typename detail::UpCast< interface_type, derived_type >::t = 0 );
307 :
308 : /** Constructor: Sets given interface pointer.
309 :
310 : @param pInterface an interface pointer
311 : */
312 : inline Reference( interface_type * pInterface );
313 :
314 : /** Constructor: Sets given interface pointer without acquiring it.
315 :
316 : @param pInterface another reference
317 : @param dummy SAL_NO_ACQUIRE to force obvious distinction to other constructors
318 : */
319 : inline Reference( interface_type * pInterface, __sal_NoAcquire dummy);
320 : /** Constructor: Sets given interface pointer without acquiring it.
321 : Deprecated, please use SAL_NO_ACQUIRE version.
322 :
323 : @deprecated
324 : @param pInterface another reference
325 : @param dummy UNO_REF_NO_ACQUIRE to force obvious distinction to other constructors
326 : */
327 : inline Reference( interface_type * pInterface, UnoReference_NoAcquire dummy );
328 :
329 : /** Constructor: Queries given interface for reference interface type (interface_type).
330 :
331 : @param rRef another reference
332 : @param dummy UNO_QUERY to force obvious distinction to other constructors
333 : */
334 : inline Reference( const BaseReference & rRef, UnoReference_Query dummy );
335 : /** Constructor: Queries given interface for reference interface type (interface_type).
336 :
337 : @param pInterface an interface pointer
338 : @param dummy UNO_QUERY to force obvious distinction to other constructors
339 : */
340 : inline Reference( XInterface * pInterface, UnoReference_Query dummy);
341 : /** Constructor: Queries given any for reference interface type (interface_type).
342 :
343 : @param rAny an any
344 : @param dummy UNO_QUERY to force obvious distinction to other constructors
345 : */
346 : inline Reference( const Any & rAny, UnoReference_Query dummy);
347 : /** Constructor: Queries given interface for reference interface type (interface_type).
348 : Throws a RuntimeException if the demanded interface cannot be queried.
349 :
350 : @param rRef another reference
351 : @param dummy UNO_QUERY_THROW to force obvious distinction
352 : to other constructors
353 : */
354 : inline Reference( const BaseReference & rRef, UnoReference_QueryThrow dummy );
355 : /** Constructor: Queries given interface for reference interface type (interface_type).
356 : Throws a RuntimeException if the demanded interface cannot be queried.
357 :
358 : @param pInterface an interface pointer
359 : @param dummy UNO_QUERY_THROW to force obvious distinction
360 : to other constructors
361 : */
362 : inline Reference( XInterface * pInterface, UnoReference_QueryThrow dummy );
363 : /** Constructor: Queries given any for reference interface type (interface_type).
364 : Throws a RuntimeException if the demanded interface cannot be queried.
365 :
366 : @param rAny an any
367 : @param dummy UNO_QUERY_THROW to force obvious distinction
368 : to other constructors
369 : */
370 : inline Reference( const Any & rAny, UnoReference_QueryThrow dummy );
371 : /** Constructor: assigns from the given interface of the same type. Throws a RuntimeException
372 : if the source interface is NULL.
373 :
374 : @param rRef another interface reference of the same type
375 : @param dummy UNO_SET_THROW to distinguish from default copy constructor
376 :
377 : @since UDK 3.2.8
378 : */
379 : inline Reference( const Reference< interface_type > & rRef, UnoReference_SetThrow dummy );
380 : /** Constructor: assigns from the given interface of the same type. Throws a RuntimeException
381 : if the source interface is NULL.
382 :
383 : @param pInterface an interface pointer
384 : @param dummy UNO_SET_THROW to distinguish from default assignment constructor
385 :
386 : @since UDK 3.2.8
387 : */
388 : inline Reference( interface_type * pInterface, UnoReference_SetThrow dummy );
389 :
390 : /** Cast operator to Reference< XInterface >: Reference objects are binary compatible and
391 : any interface must be derived from com.sun.star.uno.XInterface.
392 : This a useful direct cast possibility.
393 : */
394 31962904 : inline SAL_CALL operator const Reference< XInterface > & () const
395 31962904 : { return * reinterpret_cast< const Reference< XInterface > * >( this ); }
396 :
397 : /** Dereference operator: Used to call interface methods.
398 :
399 : @return UNacquired interface pointer
400 : */
401 226384125 : inline interface_type * SAL_CALL operator -> () const {
402 : assert(_pInterface != 0);
403 226384125 : return castFromXInterface(_pInterface);
404 : }
405 :
406 : /** Gets interface pointer. This call does not acquire the interface.
407 :
408 : @return UNacquired interface pointer
409 : */
410 67775460 : inline interface_type * SAL_CALL get() const
411 67775460 : { return castFromXInterface(_pInterface); }
412 :
413 : /** Clears reference, i.e. releases interface. Reference is null after clear() call.
414 : */
415 : inline void SAL_CALL clear();
416 :
417 : /** Sets the given interface. An interface already set will be released.
418 :
419 : @param rRef another reference
420 : @return true, if non-null interface was set
421 : */
422 : inline bool SAL_CALL set( const Reference< interface_type > & rRef );
423 : /** Sets the given interface. An interface already set will be released.
424 :
425 : @param pInterface another interface
426 : @return true, if non-null interface was set
427 : */
428 : inline bool SAL_CALL set( interface_type * pInterface );
429 :
430 : /** Sets interface pointer without acquiring it. An interface already set will be released.
431 :
432 : @param pInterface an interface pointer
433 : @param dummy SAL_NO_ACQUIRE to force obvious distinction to set methods
434 : @return true, if non-null interface was set
435 : */
436 : inline bool SAL_CALL set( interface_type * pInterface, __sal_NoAcquire dummy);
437 : /** Sets interface pointer without acquiring it. An interface already set will be released.
438 : Deprecated, please use SAL_NO_ACQUIRE version.
439 :
440 : @deprecated
441 : @param pInterface an interface pointer
442 : @param dummy UNO_REF_NO_ACQUIRE to force obvious distinction to set methods
443 : @return true, if non-null interface was set
444 : */
445 : inline bool SAL_CALL set( interface_type * pInterface, UnoReference_NoAcquire dummy);
446 :
447 : /** Queries given interface for reference interface type (interface_type) and sets it.
448 : An interface already set will be released.
449 :
450 : @param pInterface an interface pointer
451 : @param dummy UNO_QUERY to force obvious distinction to set methods
452 : @return true, if non-null interface was set
453 : */
454 : inline bool SAL_CALL set( XInterface * pInterface, UnoReference_Query dummy );
455 : /** Queries given interface for reference interface type (interface_type) and sets it.
456 : An interface already set will be released.
457 :
458 : @param rRef another reference
459 : @param dummy UNO_QUERY to force obvious distinction to set methods
460 : @return true, if non-null interface was set
461 : */
462 : inline bool SAL_CALL set( const BaseReference & rRef, UnoReference_Query dummy);
463 :
464 : /** Queries given any for reference interface type (interface_type)
465 : and sets it. An interface already set will be released.
466 :
467 : @param rAny
468 : an Any containing an interface
469 : @param dummy
470 : UNO_QUERY to force obvious distinction
471 : to set methods
472 : @return
473 : true, if non-null interface was set
474 : */
475 : inline bool set( Any const & rAny, UnoReference_Query dummy );
476 :
477 : /** Queries given interface for reference interface type (interface_type) and sets it.
478 : An interface already set will be released.
479 : Throws a RuntimeException if the demanded interface cannot be set.
480 :
481 : @param pInterface an interface pointer
482 : @param dummy UNO_QUERY_THROW to force obvious distinction
483 : to set methods
484 : */
485 : inline void SAL_CALL set( XInterface * pInterface, UnoReference_QueryThrow dummy );
486 : /** Queries given interface for reference interface type (interface_type) and sets it.
487 : An interface already set will be released.
488 : Throws a RuntimeException if the demanded interface cannot be set.
489 :
490 : @param rRef another reference
491 : @param dummy UNO_QUERY_THROW to force obvious distinction
492 : to set methods
493 : */
494 : inline void SAL_CALL set( const BaseReference & rRef, UnoReference_QueryThrow dummy );
495 :
496 : /** Queries given any for reference interface type (interface_type) and
497 : sets it. An interface already set will be released.
498 : Throws a RuntimeException if the demanded interface cannot be set.
499 :
500 : @param rAny
501 : an Any containing an interface
502 : @param dummy
503 : UNO_QUERY_THROW to force obvious distinction to set methods
504 : */
505 : inline void set( Any const & rAny, UnoReference_QueryThrow dummy);
506 : /** sets the given interface
507 : An interface already set will be released.
508 : Throws a RuntimeException if the source interface is @b NULL.
509 :
510 : @param pInterface an interface pointer
511 : @param dummy UNO_SET_THROW to force obvious distinction to other set methods
512 :
513 : @since UDK 3.2.8
514 : */
515 : inline void SAL_CALL set( interface_type * pInterface, UnoReference_SetThrow dummy);
516 : /** sets the given interface
517 : An interface already set will be released.
518 : Throws a RuntimeException if the source interface is @b NULL.
519 :
520 : @param rRef an interface reference
521 : @param dummy UNO_SET_THROW to force obvious distinction to other set methods
522 :
523 : @since UDK 3.2.8
524 : */
525 : inline void SAL_CALL set( const Reference< interface_type > & rRef, UnoReference_SetThrow dummy);
526 :
527 :
528 : /** Assignment operator: Acquires given interface pointer and sets reference.
529 : An interface already set will be released.
530 :
531 : @param pInterface an interface pointer
532 : @return this reference
533 : */
534 : inline Reference< interface_type > & SAL_CALL operator = ( interface_type * pInterface );
535 : /** Assignment operator: Acquires given interface reference and sets reference.
536 : An interface already set will be released.
537 :
538 : @param rRef an interface reference
539 : @return this reference
540 : */
541 : inline Reference< interface_type > & SAL_CALL operator = ( const Reference< interface_type > & rRef );
542 :
543 : /** Queries given interface reference for type interface_type.
544 :
545 : @param rRef interface reference
546 : @return interface reference of demanded type (may be null)
547 : */
548 : inline static SAL_WARN_UNUSED_RESULT Reference< interface_type > SAL_CALL query( const BaseReference & rRef );
549 : /** Queries given interface for type interface_type.
550 :
551 : @param pInterface interface pointer
552 : @return interface reference of demanded type (may be null)
553 : */
554 : inline static SAL_WARN_UNUSED_RESULT Reference< interface_type > SAL_CALL query( XInterface * pInterface );
555 : };
556 :
557 : /// @cond INTERNAL
558 : /** Enables boost::mem_fn and boost::bind to recognize Reference.
559 : */
560 : template <typename T>
561 19100 : inline T * get_pointer( Reference<T> const& r )
562 : {
563 19100 : return r.get();
564 : }
565 : /// @endcond
566 :
567 : }
568 : }
569 : }
570 : }
571 :
572 : #endif
573 :
574 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|