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
