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