Boost logo

Boost :

From: spamjunk (spamjunk_at_[hidden])
Date: 2002-08-24 16:08:44


What is this group's opinion on the acceptibility of macros? I figure I
better ask since that macro is getting be as unacceptable (in most circles)
as the goto and multiple inheritance. I don't use macros in any interface.
It is purely used to avoid the replication of *a lot* of code, and the
macros are #undef'd at the end of the header. It does, though, make the
code admittingly ugly.

The problem is that I want to allow the client programmer to enter a
parameter list of zero or more elements for the constructor and the SetOf
template. These of course have to be finite. I don't like to use varargs
as they are not type-safe, short-circuit optimization, and, of course, are
not allowed in template. Since they have to be finite, I want an easy why
to increase them if need be without changing a lot of code.

What I have done is use a variation of the "X macro" trick. For example
(dont' cringe):

#define PLIST X(1) Y(2) Y(3) Y(4) Y(5) Y(6) Y(7) Z(8)

template<....>
class Set {
....
// define X macros to create initializer list for the following constructor
#define X(A) element_type e ## A,
#define Y(A) Z(A),
#define Z(A) element_type e ## A = SENTINEL

    // constructor to create a set from the given elements
    explicit Set( PLIST )

#undef X
#undef Y
#undef Z
    {
        clear();

// define x macros to set bit for each element in set
#define X(A) if (e ## A != SENTINEL) set_bit(e ## A);
#define Y(A) X(A)
#define Z(A) X(A)

        PLIST
    }

#undef X1
#undef Y1
#undef Z1

.
.
.

#undef PLIST

A similar thing is done in several places, such as for the SetOf template.
To allow more parameters, it is simply a matter of adding more entries to
PLIST (changing Z(8) to Y(8), of course).

I know some would be appalled at such code, and I understand that. So, I
figure I better ask and "fix" it now.

One problem that may be seen in the above, is it may have more overhead
than:

explicit Set(element_type e1) {}
explicit Set(element_type e1, element_type e2) {}
explicit Set(element_type e1, element_type e2, element_type e3) {}

et etera, but I'm assuming that since all "unused" parameters will default
to the constant sentinel and since the constructor is inline, the optimizier
will take care of that.

Anyways, like I said, if the above is unacceptable, I will change it.

Thanks,

Rich


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