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