1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #ifndef _COMPHELPER_IMPLEMENTATIONREFERENCE_HXX 25 #define _COMPHELPER_IMPLEMENTATIONREFERENCE_HXX 26 27 #include <com/sun/star/uno/Reference.hxx> 28 #include <com/sun/star/uno/XInterface.hpp> 29 30 namespace comphelper 31 { 32 33 /** Holds a uno::Reference alongside a C++ implementation pointer 34 35 This template is useful to accomplish the following task: the 36 client needs an implementation pointer to an object providing 37 UNO interfaces. It is unsafe to simply store a C++ pointer, 38 because of the automatic UNO lifetime control. It is 39 inconvenient to always cast the UNO interface to the C++ 40 implementation, and what's more, it's mostly unclear to the 41 casual code reader. 42 43 Thus, this template nicely encapsulate the stated intention, 44 by holding a uno::Reference internally, and providing simple 45 C++ pointer semantics to the outside. As a differentiator to 46 ::rtl::Reference, this template features a getRef() method, 47 giving you friction-less access to the internal UNO interface, 48 without extra querying. 49 50 By the way, the pointer semantic of this template include 51 transitive constness. That means, if this template's instance 52 is const (e.g. because it is a member of a class which is 53 accessed in a const method), the pointer returned is also 54 const. 55 56 As this template is geared towards fast, internal pointer 57 access, validity of the UNO reference is _not_ checked for 58 every pointer access. The client of this template is 59 responsible to check that, wherever necessary, via the is() 60 method. 61 62 @tpl CppType 63 The C++ type this class should mimick a pointer to (not the 64 pointer type itself!). 65 66 @tpl UnoType 67 The UNO interface type of the object (a uno::Reference to this 68 type is held internally). 69 70 @tpl XIfType 71 An unambiguous derivative of UnoType. This is defaulted to 72 the second template parameter (UnoType), which should normally 73 just work, since one typically has only single inheritance in 74 UNO.<p> 75 Alternatively, when using the 76 ImplementationReference::createFromQuery() method to create an 77 instance, this type can serve a different need: if the 78 provided CppType only derives from XInterface (generally 79 speaking, derives from a UNO interface above UnoType in the 80 class hierarchy), then the default XIfType constitutes a 81 possibly invalid downcast to UnoType. Setting XIfType equal to 82 CppTypes's most derived UNO interface type then solves this 83 problem (which is not as arcane as it seems to be. Just 84 imagine you're providing a C++ abstract interface, which must 85 provide UNO reference semantics. Naturally, you will derive 86 this C++ interface only from XInterface, to reduce the number 87 of ambiguous classes. Even more naturally, it is reasonable to 88 have UnoType be something different from XInterface, governed 89 by the usage of the C++ interface) 90 91 @sample ImplementationReference< MyCppType, XMyInterface > 92 93 @sample ImplementationReference< MyAbstractCppType, XMyInterface, XInterface > 94 for an abstract C++ class 95 96 @see ::rtl::Reference 97 98 */ 99 template < class CppType, 100 class UnoType, 101 class XIfType=UnoType > class ImplementationReference 102 { 103 public: 104 105 typedef UnoType UnoInterfaceType; 106 typedef CppType ImplementationType; 107 typedef XIfType UnambiguousXInterfaceType; 108 109 /** Default-construct an ImplementationReference 110 111 Uno reference will be invalid, implementation pointer will 112 be NULL. 113 */ ImplementationReference()114 ImplementationReference() : 115 mxRef(), 116 mpImpl( NULL ) 117 { 118 } 119 120 /** Create an ImplementationReference from C++ pointer. 121 122 This constructor does not perform an explicit 123 QueryInterface on the provided implementation object, but 124 constructs the UNO reference directly from the given 125 pointer. This is the fastest, and most often the best way 126 to create an ImplementationReference. If the conversion 127 between the implementation object and the required UNO 128 interface is ambiguous, provide the third template 129 parameter with a type that can be unambiguously upcasted 130 to the UNO interface (the second template parameter). 131 132 There are cases, however, where performing a 133 QueryInterface is the better, albeit slower choice. In 134 these cases, createFromQuery() should be used. 135 136 @param pImpl 137 Pointer to the C++ implementation type 138 139 @see createFromQuery() 140 */ ImplementationReference(ImplementationType * pImpl)141 explicit ImplementationReference( ImplementationType* pImpl ) : 142 mxRef( static_cast<UnambiguousXInterfaceType*>(pImpl) ), 143 mpImpl( pImpl ) 144 { 145 } 146 147 struct CreateFromQuery { }; 148 /** Create an ImplementationReference from C++ pointer 149 150 @param pImpl 151 The pointer to the C++ implementation type, which is 152 queried for the template-parameterized UNO type. 153 154 @param dummy 155 Dummy parameter, to distinguish this constructor from the 156 default unary one (which does not perform a 157 QueryInterface) 158 */ ImplementationReference(ImplementationType * pImpl,CreateFromQuery)159 ImplementationReference( ImplementationType* pImpl, CreateFromQuery ) : 160 mxRef( static_cast<UnambiguousXInterfaceType*>(pImpl), 161 ::com::sun::star::uno::UNO_QUERY ), 162 mpImpl( pImpl ) 163 { 164 } 165 166 /** Factory method to create an ImplementationReference from 167 C++ pointer. 168 169 This is a static version of the constructor which creates 170 an instance of an implementation type which is explicitly 171 queried for the ImplementationReference's 172 template-parameterized UNO type. 173 174 @sample 175 mpRef = mpRef.createFromQuery( new ImplementationType ); 176 */ createFromQuery(ImplementationType * pImpl)177 static ImplementationReference createFromQuery( ImplementationType* pImpl ) 178 { 179 return ImplementationReference( pImpl, CreateFromQuery() ); 180 } 181 182 /** Query whether the pointer is still valid. 183 184 Hands off also from the implementation pointer if this 185 returns false! 186 */ is() const187 bool is() const { return mxRef.is(); } 188 189 /** Get a pointer to the implementation object 190 191 Compatibility method to get an auto_ptr-compatible 192 interface 193 */ get()194 ImplementationType* get() { return mpImpl; } get() const195 const ImplementationType* get() const { return mpImpl; } 196 197 /** Release all references 198 199 Compatibility method to get an auto_ptr-compatible 200 interface 201 */ reset()202 void reset() { dispose(); } 203 204 /** Release all references 205 206 This method releases the UNO interface reference, and 207 clears the C++ pointer to NULL. 208 */ dispose()209 void dispose() { mxRef = NULL; mpImpl=NULL; } 210 operator ->()211 ImplementationType* operator->() { return mpImpl; } operator ->() const212 const ImplementationType* operator->() const { return mpImpl; } 213 operator *()214 ImplementationType& operator*() { return *mpImpl; } operator *() const215 const ImplementationType& operator*() const { return *mpImpl; } 216 217 /// Access to the underlying UNO reference, without extra querying getRef()218 ::com::sun::star::uno::Reference< UnoInterfaceType > getRef() { return mxRef; } 219 220 /// Access to the underlying UNO reference, without extra querying getRef() const221 const ::com::sun::star::uno::Reference< UnoInterfaceType >& getRef() const { return mxRef; } 222 223 // default destructor, copy constructor and assignment will do 224 // ~ImplementationReference(); 225 // ImplementationReference( const ImplementationReference& ); 226 // ImplementationReference& operator= ( const ImplementationReference& ); 227 228 /** Comparison operator 229 230 Object identity is defined to be identity of the 231 implementation pointers. This is in general invalid when 232 comparing pointers to UNO objects (ambiguous class 233 hierarchies, optimizations in the bridges, etc.), but okay 234 for raw C++ pointers (which is what's compared herein). 235 */ operator ==(const ImplementationReference & rhs) const236 bool operator==( const ImplementationReference& rhs ) const 237 { 238 return mpImpl == rhs.mpImpl; 239 } 240 241 /** less-than operator 242 243 Object order is defined to be the ordering of the 244 implementation pointers. This is in general invalid when 245 comparing pointers to UNO objects (ambiguous class 246 hierarchies, optimizations in the bridges, etc.), but okay 247 for raw C++ pointers (which is what's used herein). 248 249 This ordering complies with STL's strict weak ordering 250 concept. 251 */ operator <(const ImplementationReference & rhs) const252 bool operator<( const ImplementationReference& rhs ) const 253 { 254 return mpImpl < rhs.mpImpl; 255 } 256 257 private: 258 259 // the interface, hard reference to prevent object from vanishing 260 ::com::sun::star::uno::Reference< UnoInterfaceType > mxRef; 261 262 // the c++ object, for our internal stuff 263 ImplementationType* mpImpl; 264 265 }; 266 267 } 268 269 #endif // _COMPHELPER_IMPLEMENTATIONREFERENCE_HXX 270