Boost logo

Boost :

From: Dean Michael Berris (mikhailberis_at_[hidden])
Date: 2006-06-12 16:05:18


On 6/12/06, Rene Rivera <grafik.list_at_[hidden]> wrote:
> Dean Michael Berris wrote:
> > Yes, this is just one of the things that the dispatcher can do. The
> > current implementation (lacking documentation) can be downloaded from
> > http://tinyurl.com/px33v --
>
> Well documentation would be what most of use would really like to see :-)
>

Yes, as I've been thinking more and more about it, I now also feel
like I should get into writing documentation for this. :)

>[...]
> dispatcher d;
> d
> << is_equal[1,true].connect(boost::bind(my_equal,_2,_3))
> << is_equal[1,false].connect(boost::bind(my_equal,_3,_2))
> << is_even[1].connect(boost::bind(my_even,_2));
> std::cout
> << ( d[is_equal,1,true](12,12) ? "T" : "F" )
> << ( d[is_equal,1,false](12,3.14) ? "T" : "F" )
> << ( d[is_even,1](2) ? "T" : "F" )
> << ( d[is_even,1](1) ? "T" : "F" )
> << std::endl;
> return 0;
> }
>
> Does your code support such varied registration and dispatching?
>

I have been mulling around the concept of allowing registration of
functions that take on different signatures, but the current state of
the library will need to be reworked to allow this kind of support. In
large part, it would duplicate a lot of the approaches taken by
Boost.Signals and encounter the same problems.

In the end though, the ultimate aim is to be able to support functions
of different signatures and register them into a single dispatcher.
The only stumbling block I'm encountering is with the actual
implementation of the overloads required to make it work -- and maybe
have to anticipate the forwarding problem, since I'll be dealing with
function pointers during runtime.

Supporting something like this is pretty tough work, as I can only
imagine the stuff that needs to be done to ensure runtime correctness
so that the following will be valid (and will perform as expected):

int my_method_1(const std::string & str) {
  std::cout << str;
  return 1;
}

void my_method_2(unsigned long long ull, const std::string & mt) {
  std::cout << ull << ", " << mt;
};

//... somewhere registered:
d[0] = boost::bind(my_method_1, _2);
d[1] = boost::bind(my_method_2, _2, _3);

//... somewhere else still
int index;
d[index]("Hello, World!");

If in case I can figure out (or others can help me figure out, or even
implement) how to make the registration and dispatch as generic as
possible without restricting that all registered functions be nullary
functions, then I might try implementing the generic registration and
dispatch. In any case, if anybody knows of a better way than looking
at Boost.Signal and seeing how it's written (which I've already done,
though partially ...) without having to go into the trouble of
"reinventing the wheel", I'd certainly appreciate the pointers. :)

> > there are a few other uses, including a
> > means for defining a strategy for index validation. An example of this
> > usage is shown below (and can also be seen from the unit test):
> [...]
> > typedef dispatch::dispatcher<int(), int, require_even_strategy,
> > std::vector> dispatcher_t;
>
> Hm, now that's an interesting idea, contract based dispatch interfaces.
>

It's usually (as far as the projects I've dealt with) a recurring
pattern, where a router is necessary to perform the required action
based on the actual message received. There are some restrictions on
the message format/composition/characteristics that need to be ensured
regardless of the actual message content -- and this can be programmed
as a strategy for determining validity of the message to guide the
dispatcher.

Since there really is no way to (that I know of) anticipate user input
during compile time, the least I can come up with is to allow for a
generic approach to allow for validating messages (indexes). This can
also be used to decide many different things during runtime, and even
change the behavior of the dispatcher as it runs.

Currently, the strategy is used for validation purposes only -- but
may and will most probably change to allow the following, and call the
appropriate callback:

dispatch::dispatcher <int (), std::string, string_normalizer> d;
d["message"] = do_something;
d["MeSsAgE"](); // will perform as though d["message"] was referenced
d["mEsSaGe"](); // same as above...
d[" message "](); // same as above...
// and many variations of "message" that can be normalized

I'm still adding more and more types of dispatchers, and currently
waiting for more interest before I even think of proposing the library
(of course, not in its current form) to the Boost C++ Library
community. If there's enough interest, I'd be glad to go through the
rogorous process of proposing the library for inclusion (and designing
it with that in mind) in the (hopefully near) future.

Right now though, it's being used in one of the projects I'm working
on which will be released under the GPL -- but the library itself is
already released under the Boost License. (And since I'm the author of
both the library and the other project, I don't expect to encounter
any issues with licensing, though IANAL).

-- 
Dean Michael C. Berris
C/C++ Software Architect
Orange and Bronze Software Labs
http://3w-agility.blogspot.com/
http://cplusplus-soup.blogspot.com/
Mobile: +639287291459
Email: dean [at] orangeandbronze [dot] com

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