From: christopher diggins (cdiggins_at_[hidden])
Date: 2005-03-04 17:53:14


----- Original Message -----
From: "Jonathan Turkanis" <technews_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Friday, March 04, 2005 5:05 PM
Subject: [boost] [interfaces] Hand written interfaces

> Hi All,
>
> I'm working on ways to make the Boost Interfaces library easier to use.

Yay!

> This
> involves making interface definitions compile faster and making them
> easier to
> read. Unfortunately, these are somewhat conflicting goals: really
> messy-looking
> interface definitions may compile much faster than simple ones.
>
> I'm working on four approaches to interface definitions; I plan to
> implement
> them all and then compare them. Right now I'm looking for feedback on
> number 4:
>
> 1. The current IDL, possibly slightly modified, in which an interface
> definition
> consists of a sequence of macro invocation
> 2. A modified IDL in which an interface definition consists of a single
> invocation; this increases the amount of preprocessor metaprogramming but
> decreases the amount of template metaprogramming
> 3. The pseudocode IDL, together with an IDL compiler which translates
> pseudocode
> definitions into C++ class definitions requiring virtually no
> metaprogramming.
> 4. Hand written interfaces, requiring virtually no metaprogramming.
>
> The point of allowing hand-written interfaces is to decrease compile
> times.
> There's no question that writing interfaces by handle will be the most
> difficult
> of the above four options. Still, writing interfaces by hand has to be
> reasonably straightforward or no one will ever do it.
>
> So here's my question. Consider the interface:
>
> interface IBar {
> void foo(const char*);
> int foo(int, int);
> };
>
> Is the following definition of IBar so complex that it would be pointless
> to
> offer it as an alternative?
> template< typename Derived,
> typename Base,
> typename Flags >
> struct ibar_impl {
> struct type : Base {
> struct interface_metadata : metadata_base<Derived, Base, Flags>
> {
> const char* names = { "foo", "foo" };
> typedef mpl::vector<
> void(const char*),
> int(int, int)
> > signatures;
> };
> void foo(const char* name)
> {
> return invoker<interface_metadata, 1>::execute(this, name);
> }
>
> int foo(int n, int m)
> {
> return invoker<interface_metadata, 2>::execute(this, int,
> int);
> }
> };
> };
>
> typedef interface< ibar_impl<_, _, _> > IBar;

I think what would happen if you did this is that users would hand roll
their own macros because it is just too ugly. That was the first thing I
tried to do when I saw it. So I don't like it.

The custom IDL pre-processor is my favourite option. One of the biggest
advantages (apart from being much much faster), is that it can also include
a built in optimizer and we will have more coherent errors output earlier.
That is by far the biggest problem with the other three options.

Christopher