1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #ifndef _COMPHELPER_IMPLEMENTATIONREFERENCE_HXX
21 #define _COMPHELPER_IMPLEMENTATIONREFERENCE_HXX
23 #include <com/sun/star/uno/Reference.hxx>
24 #include <com/sun/star/uno/XInterface.hpp>
29 /** Holds a uno::Reference alongside a C++ implementation pointer
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
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.
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
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()
59 The C++ type this class should mimick a pointer to (not the
60 pointer type itself!).
63 The UNO interface type of the object (a uno::Reference to this
64 type is held internally).
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
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)
87 @sample ImplementationReference< MyCppType, XMyInterface >
89 @sample ImplementationReference< MyAbstractCppType, XMyInterface, XInterface >
90 for an abstract C++ class
95 template < class CppType
,
97 class XIfType
=UnoType
> class ImplementationReference
101 typedef UnoType UnoInterfaceType
;
102 typedef CppType ImplementationType
;
103 typedef XIfType UnambiguousXInterfaceType
;
105 /** Default-construct an ImplementationReference
107 Uno reference will be invalid, implementation pointer will
110 ImplementationReference() :
116 /** Create an ImplementationReference from C++ pointer.
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).
128 There are cases, however, where performing a
129 QueryInterface is the better, albeit slower choice. In
130 these cases, createFromQuery() should be used.
133 Pointer to the C++ implementation type
135 @see createFromQuery()
137 explicit ImplementationReference( ImplementationType
* pImpl
) :
138 mxRef( static_cast<UnambiguousXInterfaceType
*>(pImpl
) ),
143 struct CreateFromQuery
{ };
144 /** Create an ImplementationReference from C++ pointer
147 The pointer to the C++ implementation type, which is
148 queried for the template-parameterized UNO type.
151 Dummy parameter, to distinguish this contructor from the
152 default unary one (which does not perform a
155 ImplementationReference( ImplementationType
* pImpl
, CreateFromQuery
) :
156 mxRef( static_cast<UnambiguousXInterfaceType
*>(pImpl
),
157 ::com::sun::star::uno::UNO_QUERY
),
162 /** Factory method to create an ImplementationReference from
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.
171 mpRef = mpRef.createFromQuery( new ImplementationType );
173 static ImplementationReference
createFromQuery( ImplementationType
* pImpl
)
175 return ImplementationReference( pImpl
, CreateFromQuery() );
178 /** Query whether the pointer is still valid.
180 Hands off also from the implementation pointer if this
183 bool is() const { return mxRef
.is(); }
185 /** Get a pointer to the implementation object
187 Compatibility method to get an auto_ptr-compatible
190 ImplementationType
* get() { return mpImpl
; }
191 const ImplementationType
* get() const { return mpImpl
; }
193 /** Release all references
195 Compatibility method to get an auto_ptr-compatible
198 void reset() { dispose(); }
200 /** Release all references
202 This method releases the UNO interface reference, and
203 clears the C++ pointer to NULL.
205 void dispose() { mxRef
= NULL
; mpImpl
=NULL
; }
207 ImplementationType
* operator->() { return mpImpl
; }
208 const ImplementationType
* operator->() const { return mpImpl
; }
210 ImplementationType
& operator*() { return *mpImpl
; }
211 const ImplementationType
& operator*() const { return *mpImpl
; }
213 /// Access to the underlying UNO reference, without extra querying
214 ::com::sun::star::uno::Reference
< UnoInterfaceType
> getRef() { return mxRef
; }
216 /// Access to the underlying UNO reference, without extra querying
217 const ::com::sun::star::uno::Reference
< UnoInterfaceType
>& getRef() const { return mxRef
; }
219 // default destructor, copy constructor and assignment will do
220 // ~ImplementationReference();
221 // ImplementationReference( const ImplementationReference& );
222 // ImplementationReference& operator= ( const ImplementationReference& );
224 /** Comparison operator
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).
232 bool operator==( const ImplementationReference
& rhs
) const
234 return mpImpl
== rhs
.mpImpl
;
237 /** less-than operator
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).
245 This ordering complies with STL's strict weak ordering
248 bool operator<( const ImplementationReference
& rhs
) const
250 return mpImpl
< rhs
.mpImpl
;
255 // the interface, hard reference to prevent object from vanishing
256 ::com::sun::star::uno::Reference
< UnoInterfaceType
> mxRef
;
258 // the c++ object, for our internal stuff
259 ImplementationType
* mpImpl
;
265 #endif // _COMPHELPER_IMPLEMENTATIONREFERENCE_HXX
267 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */