|
Boost : |
From: Marco Costalba (mcostalba_at_[hidden])
Date: 2007-09-18 08:34:30
On 9/18/07, Marco Costalba <mcostalba_at_[hidden]> wrote:
>
> template<typename Values, typename Args>
> Base* doObject(KeyRef nm, Values& v) const
> {
> Range r;
> if (!find_range<Args>(nm, r))
> return NULL; /* no function with the same number of arguments */
>
> const SignatureClass<Base, Args>* p = find<Args>(r);
This is the core of all the stuff.
At runtime the passed in argument types 'Args' are checked against
the factory wrappers stored in a map to see if one of them support the
same type of arguments.
template<typename Args>
const SignatureClass<Base, Args>* find(const Range& r) const
{
for (const_iterator it = r.first; it != r.second; ++it)
{
const SignatureClass<Base, Args>* p = check_type<Args>((*it).second);
if (p)
return p;
}
return NULL;
}
And finally:
template<typename Args>
const SignatureClass<Base, Args>* check_type(const StorableClass* p) const
{
// check c'tor arguments type at runtime
return dynamic_cast<const SignatureClass<Base, Args>*>(p);
}
All this dynamic plomorphism stuff is, again, necessary (at least I
haven't found nothing better) _only_ because supported classes are not
known at factory instantation time. If it was known I could use a
fusion map to store everything and the trick is done.
But a fusion map cannot be changed at runtime! If you add new classes
to your map you have a _new_ map type. So you cannot foreseen a map
variable as a member data.
That's the problem.
class factory {
....
a_fusion_map_type myFactoriesMap;
template<typename F>
void add_factory(const F& f)
{
myFactoriesMap << f; // not possible because 'a_fusion_map_type' changes
}
}
Thanks
Marco
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk