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 /** This header generates the following template classes with a variable number
25     of interfaces:
26 
27     comphelper::ImplHelper<N> <typename Ifc1, ..., typename Ifc<N> >
28     comphelper::WeakImplHelper<N> <typename Ifc1, ..., typename Ifc<N> >
29     comphelper::WeakComponentImplHelper<N> <typename Ifc1, ...,
30                                             typename Ifc<N> >
31     comphelper::ImplInheritanceHelper<N> <typename BaseClass,
32                                           typename Ifc1, ..., typename Ifc<N> >
33 
34     as already present in headers cppuhelper/implbase<1-12>.hxx and
35     cppuhelper/compbase<1-12>.hxx.
36     <N> denotes the number of interface types passed as template arguments.
37     Don't use this header for interface numbers up to 12;
38     always use the existing cppuhelper/(impl|comp)base<1-12>.hxx headers
39     for this purpose, which eases debugging.
40 
41     Including this header requires a little discipline, because it has no
42     include guards.  Please use the following external include guard rule
43     where <N> is the number of interface types:
44 
45     #if ! defined(INCLUDED_COMPHELPER_IMPLBASE_VAR_HXX_<N>)
46     #define INCLUDED_COMPHELPER_IMPLBASE_VAR_HXX_<N>
47     #define COMPHELPER_IMPLBASE_INTERFACE_NUMBER <N>
48     #include "comphelper/implbase_var.hxx"
49     #endif
50 
51     Additionally you can
52 
53     #define COMPHELPER_IMPLBASE_MAX_CTOR_ARGS <N>
54 
55     to control the maximum number of templated ctor arguments for the
56     ImplInheritanceHelper<N> classes.
57     The default is a maximum of 6 arguments.
58 */
59 
60 #if ! defined(COMPHELPER_IMPLBASE_INTERFACE_NUMBER)
61 #error "you have to define COMPHELPER_IMPLBASE_INTERFACE_NUMBER prior to including comphelper/implbase_var.hxx!"
62 #endif // ! defined(COMPHELPER_IMPLBASE_INTERFACE_NUMBER)
63 
64 #if !defined(COMPHELPER_IMPLBASE_TEST_PHASE) && COMPHELPER_IMPLBASE_INTERFACE_NUMBER <= 12
65 #error "include proper header file: cppuhelper/implbase<N>.hxx or cppuhelper/compbase<N>.hxx!"
66 #endif
67 
68 #if ! defined(COMPHELPER_IMPLBASE_MAX_CTOR_ARGS)
69 #define COMPHELPER_IMPLBASE_MAX_CTOR_ARGS 6 // default
70 #endif
71 
72 #if ! defined(_CPPUHELPER_IMPLBASE_EX_HXX_)
73 #include "cppuhelper/implbase_ex.hxx"
74 #endif
75 #if ! defined(INCLUDED_RTL_INSTANCE_HXX)
76 #include "rtl/instance.hxx"
77 #endif
78 #if ! defined(_CPPUHELPER_COMPBASE_EX_HXX_)
79 #include "cppuhelper/compbase_ex.hxx"
80 #endif
81 
82 #include "boost/preprocessor/cat.hpp"
83 #include "boost/preprocessor/repetition.hpp"
84 #include "boost/preprocessor/arithmetic/add.hpp"
85 
86 namespace comphelper {
87 
88 // Suppress warnings about hidden functions in case any of the IfcN has
89 // functions named dispose, addEventListener, or removeEventListener:
90 #if defined __SUNPRO_CC
91 #pragma disable_warn
92 #endif
93 
94 namespace detail {
95 
BOOST_PP_CAT(class_data,COMPHELPER_IMPLBASE_INTERFACE_NUMBER)96 struct BOOST_PP_CAT(class_data, COMPHELPER_IMPLBASE_INTERFACE_NUMBER)
97 {
98     sal_Int16 m_nTypes;
99     sal_Bool m_storedTypeRefs;
100     sal_Bool m_storedId;
101     sal_Int8 m_id[16];
102     ::cppu::type_entry m_typeEntries[COMPHELPER_IMPLBASE_INTERFACE_NUMBER + 1];
103 };
104 
105 /// @internal
106 template < BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER,
107                                 typename Ifc), typename Impl >
BOOST_PP_CAT(ImplClassData,COMPHELPER_IMPLBASE_INTERFACE_NUMBER)108 struct BOOST_PP_CAT(ImplClassData, COMPHELPER_IMPLBASE_INTERFACE_NUMBER)
109 {
110     ::cppu::class_data * operator()() {
111         static BOOST_PP_CAT(class_data, COMPHELPER_IMPLBASE_INTERFACE_NUMBER)
112         s_cd = {
113             COMPHELPER_IMPLBASE_INTERFACE_NUMBER + 1, sal_False, sal_False,
114             { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
115             {
116 #define COMPHELPER_IMPLBASE_classdataList(z_, n_, unused_) \
117 { { BOOST_PP_CAT(Ifc, n_)::static_type }, \
118   reinterpret_cast<sal_IntPtr>( static_cast< BOOST_PP_CAT(Ifc, n_) * >( \
119                                reinterpret_cast<Impl *>(16) ) ) - 16 },
120                 BOOST_PP_REPEAT(COMPHELPER_IMPLBASE_INTERFACE_NUMBER,
121                                 COMPHELPER_IMPLBASE_classdataList, ~)
122 #undef COMPHELPER_IMPLBASE_classdataList
123                 { { ::com::sun::star::lang::XTypeProvider::static_type },
124                   reinterpret_cast<sal_IntPtr>(
125                       static_cast< ::com::sun::star::lang::XTypeProvider * >(
126                           reinterpret_cast<Impl *>(16) ) ) - 16 }
127             }
128         };
129         return reinterpret_cast< ::cppu::class_data * >(&s_cd);
130     }
131 };
132 
133 } // namespace detail
134 
135 /** Implementation helper implementing interface
136     ::com::sun::star::lang::XTypeProvider and method
137     XInterface::queryInterface(), but no reference counting.
138 
139     @derive
140     Inherit from this class giving your interface(s) to be implemented as
141     template argument(s).  Your sub class defines method implementations for
142     these interface(s) including acquire()/release() and delegates incoming
143     queryInterface() calls to this base class.
144 */
145 template< BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER,
146                                typename Ifc) >
147 class SAL_NO_VTABLE BOOST_PP_CAT(ImplHelper,
148                                  COMPHELPER_IMPLBASE_INTERFACE_NUMBER)
149     : public ::com::sun::star::lang::XTypeProvider,
150       BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, public Ifc)
151 {
152     /// @internal
153     struct cd : public ::rtl::StaticAggregate<
154         ::cppu::class_data,
155         BOOST_PP_CAT(detail::ImplClassData,
156                      COMPHELPER_IMPLBASE_INTERFACE_NUMBER)
157         <
158             BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, Ifc),
159             BOOST_PP_CAT(ImplHelper, COMPHELPER_IMPLBASE_INTERFACE_NUMBER)<
160                 BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, Ifc)>
161         > > {};
162 
163 protected:
BOOST_PP_CAT(ImplHelper,COMPHELPER_IMPLBASE_INTERFACE_NUMBER)164     BOOST_PP_CAT(ImplHelper, COMPHELPER_IMPLBASE_INTERFACE_NUMBER)() {}
~BOOST_PP_CAT(ImplHelper,COMPHELPER_IMPLBASE_INTERFACE_NUMBER)165     virtual ~BOOST_PP_CAT(ImplHelper, COMPHELPER_IMPLBASE_INTERFACE_NUMBER)() {}
166 
167 public:
168     virtual ::com::sun::star::uno::Any
queryInterface(::com::sun::star::uno::Type const & rType)169         SAL_CALL queryInterface( ::com::sun::star::uno::Type const& rType )
170         throw (::com::sun::star::uno::RuntimeException)
171         { return ::cppu::ImplHelper_query( rType, cd::get(), this ); }
172     virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type >
getTypes()173         SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException)
174         { return ::cppu::ImplHelper_getTypes( cd::get() ); }
175     virtual ::com::sun::star::uno::Sequence<sal_Int8>
getImplementationId()176         SAL_CALL getImplementationId()
177         throw (::com::sun::star::uno::RuntimeException)
178         { return ::cppu::ImplHelper_getImplementationId( cd::get() ); }
179 };
180 
181 /** Implementation helper implementing interfaces
182     ::com::sun::star::lang::XTypeProvider and
183     ::com::sun::star::uno::XInterface
184     which supports weak mechanism to be held weakly
185     (supporting ::com::sun::star::uno::XWeak through ::cppu::OWeakObject).
186 
187     @derive
188     Inherit from this class giving your interface(s) to be implemented as
189     template argument(s).  Your sub class defines method implementations for
190     these interface(s).
191 */
192 template< BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER,
193                                typename Ifc) >
194 class SAL_NO_VTABLE BOOST_PP_CAT(WeakImplHelper,
195                                  COMPHELPER_IMPLBASE_INTERFACE_NUMBER)
196     : public ::cppu::OWeakObject,
197       public ::com::sun::star::lang::XTypeProvider,
198       BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, public Ifc)
199 {
200     /// @internal
201     struct cd : public ::rtl::StaticAggregate<
202         ::cppu::class_data,
203         BOOST_PP_CAT(detail::ImplClassData,
204                      COMPHELPER_IMPLBASE_INTERFACE_NUMBER)
205         <
206             BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, Ifc),
207             BOOST_PP_CAT(WeakImplHelper, COMPHELPER_IMPLBASE_INTERFACE_NUMBER)<
208                 BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, Ifc)>
209         > > {};
210 
211 public:
212     virtual ::com::sun::star::uno::Any
queryInterface(::com::sun::star::uno::Type const & rType)213         SAL_CALL queryInterface( ::com::sun::star::uno::Type const& rType )
214         throw (::com::sun::star::uno::RuntimeException)
215     {
216         return ::cppu::WeakImplHelper_query(
217             rType, cd::get(), this, static_cast<OWeakObject *>(this) );
218     }
acquire()219     virtual void SAL_CALL acquire() throw ()
220         { OWeakObject::acquire(); }
release()221     virtual void SAL_CALL release() throw ()
222         { OWeakObject::release(); }
223     virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type >
getTypes()224         SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException)
225         { return ::cppu::WeakImplHelper_getTypes( cd::get() ); }
226     virtual ::com::sun::star::uno::Sequence<sal_Int8>
getImplementationId()227         SAL_CALL getImplementationId()
228         throw (::com::sun::star::uno::RuntimeException)
229         { return ::cppu::ImplHelper_getImplementationId( cd::get() ); }
230 };
231 
232 /** Implementation helper implementing interfaces
233     ::com::sun::star::lang::XTypeProvider and
234     ::com::sun::star::uno::XInterface inherting from a BaseClass.
235 
236     All acquire() and release() calls are delegated to the BaseClass.
237     Upon queryInterface(), if a demanded interface is not supported by this
238     class directly, the request is delegated to the BaseClass.
239 
240     @attention
241     The BaseClass has to be complete in a sense, that
242     ::com::sun::star::uno::XInterface and
243     ::com::sun::star::lang::XTypeProvider are implemented properly.
244     The BaseClass must have at least one ctor that can be called with
245     COMPHELPER_IMPLBASE_MAX_CTOR_ARGS or fewer arguments.
246 
247     @derive
248     Inherit from this class giving your additional interface(s) to be
249     implemented as template argument(s).  Your sub class defines method
250     implementations for these interface(s).
251 */
252 template <typename BaseClass,
253           BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER,
254                                typename Ifc) >
255 class SAL_NO_VTABLE BOOST_PP_CAT(ImplInheritanceHelper,
256                                  COMPHELPER_IMPLBASE_INTERFACE_NUMBER)
257     : public BaseClass,
258       BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, public Ifc)
259 {
260     /// @internal
261     struct cd : public ::rtl::StaticAggregate<
262         ::cppu::class_data,
263         BOOST_PP_CAT(detail::ImplClassData,
264                      COMPHELPER_IMPLBASE_INTERFACE_NUMBER)
265         <
266             BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, Ifc),
267             BOOST_PP_CAT(ImplInheritanceHelper,
268                          COMPHELPER_IMPLBASE_INTERFACE_NUMBER)<
269                 BaseClass,
270                 BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, Ifc)>
271         > > {};
272 
273 protected:
274 #define COMPHELPER_IMPLBASE_templctor_args(z_, n_, unused_) \
275     BOOST_PP_CAT(T, n_) const& BOOST_PP_CAT(arg, n_)
276 #define COMPHELPER_IMPLBASE_templctor(z_, n_, classname_) \
277     template< BOOST_PP_ENUM_PARAMS( BOOST_PP_ADD(n_, 1), typename T) > \
278     explicit BOOST_PP_CAT(classname_, COMPHELPER_IMPLBASE_INTERFACE_NUMBER)( \
279         BOOST_PP_ENUM(BOOST_PP_ADD(n_, 1), \
280                       COMPHELPER_IMPLBASE_templctor_args, ~) ) \
281         : BaseClass( BOOST_PP_ENUM_PARAMS(BOOST_PP_ADD(n_, 1), arg) ) {}
282 
BOOST_PP_CAT(ImplInheritanceHelper,COMPHELPER_IMPLBASE_INTERFACE_NUMBER)283     BOOST_PP_CAT(ImplInheritanceHelper, COMPHELPER_IMPLBASE_INTERFACE_NUMBER)()
284         : BaseClass() {}
285     BOOST_PP_REPEAT(COMPHELPER_IMPLBASE_MAX_CTOR_ARGS,
286                     COMPHELPER_IMPLBASE_templctor, ImplInheritanceHelper)
287 
288 public:
289     virtual ::com::sun::star::uno::Any
queryInterface(::com::sun::star::uno::Type const & rType)290         SAL_CALL queryInterface( ::com::sun::star::uno::Type const& rType )
291         throw (::com::sun::star::uno::RuntimeException)
292     {
293         ::com::sun::star::uno::Any const aRet(
294             ::cppu::ImplHelper_queryNoXInterface( rType, cd::get(), this ) );
295         if (aRet.hasValue())
296             return aRet;
297         return BaseClass::queryInterface( rType );
298     }
acquire()299     virtual void SAL_CALL acquire() throw ()
300         { BaseClass::acquire(); }
release()301     virtual void SAL_CALL release() throw ()
302         { BaseClass::release(); }
303     virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type >
getTypes()304         SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException)
305     {
306         return ::cppu::ImplInhHelper_getTypes(
307             cd::get(), BaseClass::getTypes() );
308     }
309     virtual ::com::sun::star::uno::Sequence<sal_Int8>
getImplementationId()310         SAL_CALL getImplementationId()
311         throw (::com::sun::star::uno::RuntimeException)
312         { return ::cppu::ImplHelper_getImplementationId( cd::get() ); }
313 };
314 
315 // not needed anymore:
316 #undef COMPHELPER_IMPLBASE_templctor_args
317 #undef COMPHELPER_IMPLBASE_templctor
318 
319 /** Implementation helper supporting
320     ::com::sun::star::lang::XTypeProvider and
321     ::com::sun::star::lang::XComponent.
322 
323     Upon disposing objects of this class, sub-classes receive a disposing()
324     call.  Objects of this class can be held weakly, i.e. by a
325     ::com::sun::star::uno::WeakReference.
326 
327     @attention
328     The life-cycle of the passed mutex reference has to be longer than objects
329     of this class.
330 
331     @derive
332     Inherit from this class giving your interface(s) to be implemented as
333     template argument(s).  Your sub class defines method implementations for
334     these interface(s).
335 */
336 template < BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER,
337                                 typename Ifc) >
338 class SAL_NO_VTABLE BOOST_PP_CAT(WeakComponentImplHelper,
339                                  COMPHELPER_IMPLBASE_INTERFACE_NUMBER)
340     : public ::cppu::WeakComponentImplHelperBase,
341       public ::com::sun::star::lang::XTypeProvider,
342       BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, public Ifc)
343 {
344     /// @internal
345     struct cd : public ::rtl::StaticAggregate<
346         ::cppu::class_data,
347         BOOST_PP_CAT(detail::ImplClassData,
348                      COMPHELPER_IMPLBASE_INTERFACE_NUMBER)
349         <
350             BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, Ifc),
351             BOOST_PP_CAT(WeakComponentImplHelper,
352                          COMPHELPER_IMPLBASE_INTERFACE_NUMBER)<
353                 BOOST_PP_ENUM_PARAMS(COMPHELPER_IMPLBASE_INTERFACE_NUMBER, Ifc)>
354         > > {};
355 
356 public:
BOOST_PP_CAT(WeakComponentImplHelper,COMPHELPER_IMPLBASE_INTERFACE_NUMBER)357     BOOST_PP_CAT(WeakComponentImplHelper, COMPHELPER_IMPLBASE_INTERFACE_NUMBER)(
358         ::osl::Mutex & rMutex ) : WeakComponentImplHelperBase(rMutex) {}
359 
360     virtual ::com::sun::star::uno::Any
queryInterface(::com::sun::star::uno::Type const & rType)361         SAL_CALL queryInterface( ::com::sun::star::uno::Type const& rType )
362         throw (::com::sun::star::uno::RuntimeException)
363     {
364         return ::cppu::WeakComponentImplHelper_query(
365             rType, cd::get(), this,
366             static_cast< ::cppu::WeakComponentImplHelperBase * >(this) );
367     }
acquire()368     virtual void SAL_CALL acquire() throw ()
369         { WeakComponentImplHelperBase::acquire(); }
release()370     virtual void SAL_CALL release() throw ()
371         { WeakComponentImplHelperBase::release(); }
372     virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type >
getTypes()373         SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException)
374         { return ::cppu::WeakComponentImplHelper_getTypes( cd::get() ); }
375     virtual ::com::sun::star::uno::Sequence<sal_Int8>
getImplementationId()376         SAL_CALL getImplementationId()
377         throw (::com::sun::star::uno::RuntimeException)
378         { return ::cppu::ImplHelper_getImplementationId( cd::get() ); }
379 
380     // implement XComponent directly avoiding ambiguities:
dispose()381     virtual void SAL_CALL dispose()
382         throw (::com::sun::star::uno::RuntimeException)
383         { WeakComponentImplHelperBase::dispose(); }
addEventListener(::com::sun::star::uno::Reference<::com::sun::star::lang::XEventListener> const & xListener)384     virtual void SAL_CALL addEventListener(
385         ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener>
386         const & xListener ) throw (::com::sun::star::uno::RuntimeException)
387         { WeakComponentImplHelperBase::addEventListener( xListener ); }
removeEventListener(::com::sun::star::uno::Reference<::com::sun::star::lang::XEventListener> const & xListener)388     virtual void SAL_CALL removeEventListener(
389         ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener>
390         const & xListener ) throw (::com::sun::star::uno::RuntimeException)
391         { WeakComponentImplHelperBase::removeEventListener( xListener ); }
392 };
393 
394 } // namespace comphelper
395 
396 // undef for multiple use/inclusion of this header:
397 #undef COMPHELPER_IMPLBASE_MAX_CTOR_ARGS
398 #undef COMPHELPER_IMPLBASE_INTERFACE_NUMBER
399 
400