Boost logo

Boost :

From: Marco Costalba (mcostalba_at_[hidden])
Date: 2007-09-05 07:12:52


I'm extending the 'simple object factory' I have presented to this
mailing list few threads ago.

It is coming out pretty nice: the number of allowed object c'tor
arguments have been extended until a given maximum and instead of an
(optional) custom "object creator" function it is now possible to use
any callable entity as example a functor object.

The factory is now "almost" satisfactory. It has only a couple of
drawbacks, one small and a work around does exist. The other is
"important" because is a design issue.

Very briefly:

I can register any c'tor anywhere in a program to teach the factory
how to build an object:

Factory::register_class<Base, double>("MyObject");
Factory::register_class<Base, int, Base*>("MyObject");

Above instructions automatically instantiate and register two c'tor
invokers c1 and c2 defined as:

Base* c1(double d) { return new Base(d); }

Base* c2(int i, Base* b) { return new Base(i, b); }

Constructor overloading support it means that the factory will call
two different functions also if the same key "MyObject" is passed
depending on the argument types:

Base* o1 = Factory::object("MyObject", 3.14); /* function 'c1' is called */
Base* o2 = Factory::object("MyObject", 3, o1); /* function 'c2' is called */

The factory is also able to check the signatures at runtime and
discards any wrong call:

Base* o3 = Factory::object("MyObject", o1, 3); /* o3 == NULL */

Finally, here it is the current big limitation: automatic argument
type conversion is not supported:

Factory::object("MyObject", 3.14, o1); /* fails: double -> int is not done */

Derived* d = new Derived(); /* say Derived it's a sub class of Base */

Factory::object("MyObject", 3, d); /* fails: Derived* -> Base* is not done */

The design issue is that type info is templatized so that only "near
perfect matches" are discovered.

Where "near perfect matches" it means that if a value 'v' has type V
and constructor
argument accepts type A then we have a match only if:

       A == V || A == V& || A == const V || A == const V&

My question is: there exsist a way to check "relaxed" signatures at run-time?

Put in general terms: Given a set 'Set' of functor objects f1,f2,..fn
with different signatures in their operator() is it possible to check
if a given set of values v1,v2,...vk are compatible with one or more
of them ?

What I would need is an implementation of the following algorithm:

foreach(f in Set)
   if ( "f(v1,v2,..,vk)" is compilable )
      return f;

Constrains are:

- Functors can be "registered" with the factory in different times and
in different translation units.

- At runtime you have a only set of values as input: v1,..vk

- Functor signatures may not be homogeneous

Thanks for your help
Marco


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk