Update SWORD integration to work with sword 1.6.0 (which is now required for sword...
[kworship.git] / include / VTable.h
bloba0b7f30bc236a6bb588687011a15b8b1eaec2956
1 /***************************************************************************
2 * This file is part of KWorship. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
4 * *
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. *
9 * *
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. *
14 * *
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 ***************************************************************************/
20 #ifndef _VTable_h_
21 #define _VTable_h_
23 /**
24 * @file VTable.h
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.
32 /**
33 * @param Base Base class.
34 * @param Sig Signiture of virtual function.
36 template <typename Base, typename Sig>
37 class VTable
40 * Type declarations
43 class BaseImplementation;
44 template <typename T> class Implementation;
46 public:
49 * Constructors + destructor
52 /// Default constructor.
53 VTable()
57 /// Destructor.
58 virtual ~VTable()
60 foreach (BaseImplementation* impl, m_implementations)
62 delete impl;
67 * Main interface
70 /// Add an implementation.
71 /**
72 * @param T Derived class.
73 * @param impl Function pointer to implementation.
75 template <typename F>
76 void addImplementation(F impl)
78 m_implementations += new PointerImplementation<typename meta::PointerInfo<typename meta::ParameterInfo<F,0>::Type>::Type>(impl);
81 template <typename T>
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))
107 return true;
110 return false;
113 bool test(Base* base)
115 foreach (BaseImplementation* impl, m_implementations)
117 if (impl->test(base))
119 return true;
122 return false;
125 private:
128 * Types
131 class BaseImplementation
133 public:
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
144 public:
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);
151 if (derived != 0)
153 meta::FunctionInfo<Sig>::template unpack<FUNCTOR, T*>(derived, params);
154 return true;
156 else
158 return false;
161 virtual bool test(Base* base) const
163 return dynamic_cast<T*>(base) != 0;
165 private:
166 typename meta::FunctionInfo<Sig>::template Unshift<T>::Pointer m_impl;
169 template <typename T>
170 class PointerImplementation : public BaseImplementation
172 public:
173 PointerImplementation(typename meta::FunctionInfo<Sig>::template Unshift<T*>::Pointer impl)
174 : m_impl(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);
183 if (derived != 0)
185 meta::FunctionInfo<Sig>::template call(m_impl, derived, params);
186 return true;
188 else
190 return false;
193 virtual bool test(Base* base) const
195 return dynamic_cast<T*>(base) != 0;
197 private:
198 typename meta::FunctionInfo<Sig>::template Unshift<T*>::Pointer m_impl;
202 * Variables
205 /// Have a big list of implementations.
206 QList<BaseImplementation*> m_implementations;
210 #endif // _VTable_h_