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