update credits
[LibreOffice.git] / include / cppuhelper / implbase.hxx
blob06ac7a8c8d1ab8f2b6cf8fc09c2c5af36ab2bf65
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
19 #ifndef _CPPUHELPER_IMPLBASE_HXX_
20 #define _CPPUHELPER_IMPLBASE_HXX_
22 #include <osl/mutex.hxx>
23 #include <cppuhelper/weak.hxx>
24 #include <cppuhelper/weakagg.hxx>
25 #include <rtl/instance.hxx>
27 #include <com/sun/star/lang/XTypeProvider.hpp>
28 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
29 #include "cppuhelperdllapi.h"
31 /* This header should not be used anymore.
32 @deprecated
35 /// @cond INTERNAL
37 namespace cppu
40 /** Struct used for inline template implementation helpers: type entries.
41 Not for public use.
43 struct Type_Offset
45 /** binary offset of vtable pointer from object base
47 sal_Int32 nOffset;
48 /** interface type description of interface entry
50 typelib_InterfaceTypeDescription * pTD;
52 /** Struct used for inline template implementation helpers: class data of implementation.
53 Not for public use.
55 struct CPPUHELPER_DLLPUBLIC ClassDataBase
57 /** determines whether the class data has been statically initialized
59 sal_Bool bOffsetsInit;
60 /** length of static array ClassDataN
62 sal_Int32 nType2Offset;
64 /** class code determines which standard types are supported (and returned on
65 com.sun.star.lang.XTypeProvider::getTypes()) by the helper:
67 - 1 -- com.sun.star.uno.XWeak
68 - 2 -- com.sun.star.uno.XWeak, com.sun.star.uno.XAggregation
69 - 3 -- com.sun.star.uno.XWeak, com.sun.star.uno.XAggregation, com.sun.star.lang.XComponent
70 - 4 -- com.sun.star.uno.XWeak, com.sun.star.lang.XComponent
72 sal_Int32 nClassCode;
74 /** pointer to types sequence (com.sun.star.lang.XTypeProvider)
76 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > * pTypes;
77 /** pointer to class id (com.sun.star.lang.XTypeProvider)
79 ::com::sun::star::uno::Sequence< sal_Int8 > * pId;
81 /** def ctor
83 ClassDataBase() SAL_THROW(());
84 /** class code ctor
86 @param nClassCode class code, see ClassDataBase::nClassCode
88 ClassDataBase( sal_Int32 nClassCode ) SAL_THROW(());
89 /** dtor
91 ~ClassDataBase() SAL_THROW(());
93 /** Struct used for inline template implementation helpers:
94 There will be versions of this struct with varying arType2Offset[] array sizes, each of which
95 is binary compatible with this one to be casted and used uniform. The size of the varying array
96 is set in ClassDataBase::nType2Offset (base class).
97 Not for public use.
99 struct CPPUHELPER_DLLPUBLIC ClassData : public ClassDataBase
101 /** type entries array
103 Type_Offset arType2Offset[1];
105 /** init call for supporting com.sun.star.lang.XTypeProvider
107 void SAL_CALL initTypeProvider() SAL_THROW(());
108 /** initial writing type offsets for vtables
110 @param rType type of interface
111 @param nOffset offset to vtable entry
113 void SAL_CALL writeTypeOffset( const ::com::sun::star::uno::Type & rType, sal_Int32 nOffset )
114 SAL_THROW(());
116 /** Queries for an interface.
118 @param rType demanded interface type
119 @pBase base this pointer related when writing type offsets (writeTypeOffset())
120 @return demanded interface or empty any
122 ::com::sun::star::uno::Any SAL_CALL query(
123 const ::com::sun::star::uno::Type & rType, ::com::sun::star::lang::XTypeProvider * pBase )
124 SAL_THROW(());
125 /** Gets the types for supporting com.sun.star.lang.XTypeProvider
127 @return sequence of types supported
129 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes()
130 SAL_THROW(());
131 /** Gets the class id of implementation supporting com.sun.star.lang.XTypeProvider
133 @return class identifier (sequence< byte >)
135 ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId()
136 SAL_THROW(());
139 /** Shared mutex for implementation helper initialization.
140 Not for public use.
142 CPPUHELPER_DLLPUBLIC ::osl::Mutex & SAL_CALL getImplHelperInitMutex(void) SAL_THROW(());
146 // settle down beavis, here comes the macro template hell :]
149 //==================================================================================================
151 #if defined _MSC_VER // public -> protected changes mangled names there
152 #define CPPUHELPER_DETAIL_IMPLHELPER_PROTECTED public
153 #else
154 #define CPPUHELPER_DETAIL_IMPLHELPER_PROTECTED protected
155 #endif
157 /** Implementation helper macros
158 Not for common use. There are expanded forms of the macro usage in implbaseN.hxx/compbaseN.hxx.
159 So there is commonly no need to use these macros. Though, you may need to implement more than
160 12 interfaces. Then you have to declare something like the following in your headers
161 (where N is your demanded number of interfaces):
163 #define __IFC3 Ifc1, Ifc2, Ifc3, ... up to N
164 #define __CLASS_IFC3 class Ifc1, class Ifc2, class Ifc3, ... up to N
165 #define __PUBLIC_IFC3 public Ifc1, public Ifc2, public Ifc3, ... up to N
166 __DEF_IMPLHELPER_PRE( N )
167 __IFC_WRITEOFFSET( 1 ) __IFC_WRITEOFFSET( 2 ) __IFC_WRITEOFFSET( 3 ), ... up to N
168 __DEF_IMPLHELPER_POST( N )
170 #define __DEF_IMPLHELPER_PRE( N ) \
171 namespace cppu \
173 struct ClassData##N : public ClassDataBase \
175 Type_Offset arType2Offset[ N ]; \
176 ClassData##N( sal_Int32 nInClassCode ) SAL_THROW(()) \
177 : ClassDataBase( nInClassCode ) \
178 {} \
179 }; \
180 template< __CLASS_IFC##N > \
181 class SAL_NO_VTABLE SAL_DLLPUBLIC_TEMPLATE ImplHelperBase##N \
182 : public ::com::sun::star::lang::XTypeProvider \
183 , __PUBLIC_IFC##N \
185 CPPUHELPER_DETAIL_IMPLHELPER_PROTECTED: \
186 ~ImplHelperBase##N() throw () {} \
187 protected: \
188 ClassData & SAL_CALL getClassData( ClassDataBase & s_aCD ) SAL_THROW(()) \
190 ClassData & rCD = * static_cast< ClassData * >( &s_aCD ); \
191 if (! rCD.bOffsetsInit) \
193 ::osl::MutexGuard aGuard( getImplHelperInitMutex() ); \
194 if (! rCD.bOffsetsInit) \
196 char * pBase = (char *)this;
197 /** Implementation helper macro: have a look at __DEF_IMPLHELPER_PRE
199 #define __IFC_WRITEOFFSET( N ) \
200 rCD.writeTypeOffset( ::getCppuType( (const ::com::sun::star::uno::Reference< Ifc##N > *)0 ), \
201 (char *)(Ifc##N *)this - pBase );
202 /** Implementation helper macro: have a look at __DEF_IMPLHELPER_PRE
204 #define __DEF_IMPLHELPER_POST_A( N ) \
205 rCD.bOffsetsInit = sal_True; \
208 return rCD; \
210 }; \
211 template< __CLASS_IFC##N > \
212 class SAL_NO_VTABLE SAL_DLLPUBLIC_TEMPLATE ImplHelper##N \
213 : public ImplHelperBase##N< __IFC##N > \
215 static ClassData##N s_aCD; \
216 public: \
217 virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw (::com::sun::star::uno::RuntimeException) \
218 { return this->getClassData( s_aCD ).query( rType, (ImplHelperBase##N< __IFC##N > *)this ); } \
219 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException) \
220 { return this->getClassData( s_aCD ).getTypes(); } \
221 virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException) \
222 { return this->getClassData( s_aCD ).getImplementationId(); } \
223 CPPUHELPER_DETAIL_IMPLHELPER_PROTECTED: \
224 ~ImplHelper##N() throw () {} \
225 }; \
226 template< __CLASS_IFC##N > \
227 class SAL_NO_VTABLE SAL_DLLPUBLIC_TEMPLATE WeakImplHelper##N \
228 : public ::cppu::OWeakObject \
229 , public ImplHelperBase##N< __IFC##N > \
231 static ClassData##N s_aCD; \
232 public: \
233 virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw (::com::sun::star::uno::RuntimeException) \
235 ::com::sun::star::uno::Any aRet( this->getClassData( s_aCD ).query( rType, (ImplHelperBase##N< __IFC##N > *)this ) ); \
236 return (aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType )); \
238 virtual void SAL_CALL acquire() throw () \
239 { OWeakObject::acquire(); } \
240 virtual void SAL_CALL release() throw () \
241 { OWeakObject::release(); } \
242 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException) \
243 { return this->getClassData( s_aCD ).getTypes(); } \
244 virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException) \
245 { return this->getClassData( s_aCD ).getImplementationId(); } \
246 }; \
247 template< __CLASS_IFC##N > \
248 class SAL_NO_VTABLE SAL_DLLPUBLIC_TEMPLATE WeakAggImplHelper##N \
249 : public ::cppu::OWeakAggObject \
250 , public ImplHelperBase##N< __IFC##N > \
252 static ClassData##N s_aCD; \
253 public: \
254 virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw (::com::sun::star::uno::RuntimeException) \
255 { return OWeakAggObject::queryInterface( rType ); } \
256 virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type & rType ) throw (::com::sun::star::uno::RuntimeException) \
258 ::com::sun::star::uno::Any aRet( this->getClassData( s_aCD ).query( rType, (ImplHelperBase##N< __IFC##N > *)this ) ); \
259 return (aRet.hasValue() ? aRet : OWeakAggObject::queryAggregation( rType )); \
261 virtual void SAL_CALL acquire() throw () \
262 { OWeakAggObject::acquire(); } \
263 virtual void SAL_CALL release() throw () \
264 { OWeakAggObject::release(); } \
265 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException) \
266 { return this->getClassData( s_aCD ).getTypes(); } \
267 virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException) \
268 { return this->getClassData( s_aCD ).getImplementationId(); } \
271 /** Implementation helper macro: have a look at __DEF_IMPLHELPER_PRE
273 #define __DEF_IMPLHELPER_POST_B( N ) \
274 template< __CLASS_IFC##N > \
275 ClassData##N ImplHelper##N< __IFC##N >::s_aCD = ClassData##N( 0 ); \
276 template< __CLASS_IFC##N > \
277 ClassData##N WeakImplHelper##N< __IFC##N >::s_aCD = ClassData##N( 1 ); \
278 template< __CLASS_IFC##N > \
279 ClassData##N WeakAggImplHelper##N< __IFC##N >::s_aCD = ClassData##N( 2 );
280 /** Implementation helper macro: have a look at __DEF_IMPLHELPER_PRE
282 #define __DEF_IMPLHELPER_POST_C( N ) \
284 //==================================================================================================
285 /** Implementation helper macro: have a look at __DEF_IMPLHELPER_PRE
287 #define __DEF_IMPLHELPER_POST( N ) \
288 __DEF_IMPLHELPER_POST_A( N ) \
289 __DEF_IMPLHELPER_POST_B( N ) \
290 __DEF_IMPLHELPER_POST_C( N )
292 /// @endcond
294 #endif
296 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */