1 /***************************************************************************
2 * This file is part of KWorship. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
5 * KWorship is free software: you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation, either version 2 of the License, or *
8 * (at your option) any later version. *
10 * KWorship is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with KWorship. If not, write to the Free Software Foundation, *
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18 ***************************************************************************/
25 * @brief Generic run-time VTable implementation, useful for filter plugins.
26 * @author James Hogan <james@albanarts.com>
29 #include "functionInfo.h"
31 /// Generic run-time VTable implementation.
33 * @param Base Base class.
34 * @param Sig Signiture of virtual function.
36 template <typename Base
, typename Sig
>
43 class BaseImplementation
;
44 template <typename T
> class Implementation
;
49 * Constructors + destructor
52 /// Default constructor.
60 foreach (BaseImplementation
* impl
, m_implementations
)
70 /// Add an implementation.
72 * @param T Derived class.
73 * @param impl Function pointer to implementation.
76 void addImplementation(F impl
)
78 m_implementations
+= new PointerImplementation
<typename
meta::PointerInfo
<typename
meta::ParameterInfo
<F
,0>::Type
>::Type
>(impl
);
82 void addImplementation(typename meta::FunctionInfo<Sig>::template Unshift<T*>::Pointer impl)
84 m_implementations += new PointerImplementation<T>(impl);
87 template <typename T
, typename FUNCTOR
>
88 void addImplementation()
90 m_implementations
+= new FunctorImplementation
<T
, FUNCTOR
>();
93 bool operator () (Base
* base
) const { return callPack(base
, meta::FunctionInfo
<Sig
>::Params::pack()); }
94 template <typename P1
>
95 bool operator () (Base
* base
, P1 p1
) const { return callPack(base
, meta::FunctionInfo
<Sig
>::Params::pack(p1
)); }
96 template <typename P1
, typename P2
>
97 bool operator () (Base
* base
, P1 p1
, P2 p2
) const { return callPack(base
, meta::FunctionInfo
<Sig
>::Params::pack(p1
,p2
)); }
98 template <typename P1
, typename P2
, typename P3
>
99 bool operator () (Base
* base
, P1 p1
, P2 p2
, P3 p3
) const { return callPack(base
, meta::FunctionInfo
<Sig
>::Params::pack(p1
,p2
,p3
)); }
101 bool callPack(Base
* base
, const typename
meta::FunctionInfo
<Sig
>::Params::Pack
& params
) const
103 foreach (BaseImplementation
* impl
, m_implementations
)
105 if (impl
->call(base
, params
))
113 bool test(Base
* base
)
115 foreach (BaseImplementation
* impl
, m_implementations
)
117 if (impl
->test(base
))
131 class BaseImplementation
134 virtual ~BaseImplementation()
137 virtual bool call(Base
* base
, const typename
meta::FunctionInfo
<Sig
>::Params::Pack
& params
) const = 0;
138 virtual bool test(Base
* base
) const = 0;
141 template <typename T
, typename FUNCTOR
>
142 class FunctorImplementation
: public BaseImplementation
145 virtual ~FunctorImplementation()
148 virtual bool call(Base
* base
, const typename
meta::FunctionInfo
<Sig
>::Params::Pack
& params
) const
150 T
* derived
= dynamic_cast<T
*>(base
);
153 meta::FunctionInfo
<Sig
>::template unpack
<FUNCTOR
, T
*>(derived
, params
);
161 virtual bool test(Base
* base
) const
163 return dynamic_cast<T
*>(base
) != 0;
166 typename
meta::FunctionInfo
<Sig
>::template Unshift
<T
>::Pointer m_impl
;
169 template <typename T
>
170 class PointerImplementation
: public BaseImplementation
173 PointerImplementation(typename
meta::FunctionInfo
<Sig
>::template Unshift
<T
*>::Pointer impl
)
177 virtual ~PointerImplementation()
180 virtual bool call(Base
* base
, const typename
meta::FunctionInfo
<Sig
>::Params::Pack
& params
) const
182 T
* derived
= dynamic_cast<T
*>(base
);
185 meta::FunctionInfo
<Sig
>::template call(m_impl
, derived
, params
);
193 virtual bool test(Base
* base
) const
195 return dynamic_cast<T
*>(base
) != 0;
198 typename
meta::FunctionInfo
<Sig
>::template Unshift
<T
*>::Pointer m_impl
;
205 /// Have a big list of implementations.
206 QList
<BaseImplementation
*> m_implementations
;