Boost logo

Boost :

From: Terje Slettebø (tslettebo_at_[hidden])
Date: 2003-01-29 12:07:35


>From: "John Maddock" <jm_at_[hidden]>

> > Before changing the documentation please consider the following improved
> > implemetation that overcomes ambiguity and access control issues of the
> > current is_base_and_derived implemetation (I lately posted it to
> c.l.c++.m)
>
> That's really interesting, but I can't get to work with the compilers I
have
> access to (Borland/gcc), I've attached a modified version that at least
> compiles with these compilers, but it doesn't produce the correct results:

The following version works on g++ for the same cases that the current
is_base_and_derived works (i.e. excluding multiple bases, and
private/protected inheritance), and gives an error in the cases it doesn't
work, while it works completely on the compilers that supports this (such as
Comeau C++ and Intel C++ 6/7). In other words, it "degrades gracefully", and
breaks noisily, if the compiler doesn't support the extra cases. This is
tested on Comeau 4.3, Intel C++ 6/7 and g++ 3.2.

You could get the same effect with #ifdef between Rani's original version,
and the current Boost version, but the following version makes the #ifdef
unnecessary.

template<typename B, typename D>
struct helper
{
    template<typename T>
    static char check(D const volatile &, T);
    static char (& check(B const volatile &, int))[2];

    struct C
    {
        operator B const volatile &() const;
        operator D const volatile &();
    };

    static C getC();
};

template<typename B, typename D>
struct is_base_and_derived
{
    static const bool result =
        sizeof(helper<B,D>::check(helper<B,D>::getC(), 0)) == 1;
};

// If strict interpretation, i.e. not its own base class

template<typename T>
struct is_base_and_derived<T, T>
{
    static const bool result = false;
};

struct B {};
struct B1 : B {};
struct B2 : B {};
struct D : B1, private B2 {};

struct BV1 : virtual B {};
struct BV2 : virtual B {};
struct DV : BV1, BV2 {};

// g++ doesn't like multiple definitions of the same typedef, therefore they
have different names

typedef char TestA[is_base_and_derived<B, D>::result]; // Multiple bases
(error on g++)
typedef char TestB[is_base_and_derived<B1,D>::result];
typedef char TestC[is_base_and_derived<B2,D>::result]; // Private base
(error on g++)
typedef char TestD[!is_base_and_derived<int,D>::result];
typedef char TestE[!is_base_and_derived<B, B>::result];
typedef char TestF[is_base_and_derived<B,DV>::result]; // Virtual base

int main()
{
}

Regards,

Terje


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