Boost logo

Boost :

From: Alisdair Meredith (alisdair.meredith_at_[hidden])
Date: 2003-08-05 10:50:06


David Abrahams wrote:

> Err, I don't get it. It seems to me that you only need the hack if
> you're going to *specialize* swap. *Using* std::swap should work just
> fine.

OK, that's because I was confused <g>
The following is really a minimal example, so I can be clearer this
time:

#include <boost/shared_ptr.hpp>

class empty
{
};

//#define DEMONSTRATE_BUG
# if defined( DEMONSTRATE_BUG )
namespace std
{
template<>
void swap( empty &lhs, empty &rhs )
{
}

}
# endif

int main(int argc, char* argv[])
{
    boost::shared_ptr<int> pA( new int );
    pA.reset();

    return 0;
}

If we #define DEMONSTRATE_BUG the pA.reset() will cause:
[C++ Error] shared_ptr.hpp(286): E2285 Could not find a match for
'std::swap<>(int *,int *)'

Without the define, everything is fine.

This time it is clear that the swap specialization is nothing to do with
the shared_ptrs I want to swap. That was my misunderstanding. Creating
ANY specialization is going to trip up the borland parser.

The problem is that many boost libraries use std::swap. These are prone
to breaking the instant a user (or another of their library vendors)
makes the appropriate specialization.

The fix I am currently using looks like this in shared_ptr [line 284]

    void swap(shared_ptr<T> & other) // never throws
    {
    #if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x0564) )
        _STL::swap(px, other.px);
    #else
        std::swap(px, other.px);
    #endif
        pn.swap(other.pn);
    }

I am not submitting this as a diff yet as I am not sure this is the
'correct' patch yet, but I hope it gives the idea. A similar patch
needs to be applied everywhere in Boost std::swap is called, which could
be quite a bit of work. I am happy to go through all the libraries and
submit appropriate diffs, but first I would like agreement a patch is
appropriate, and the correct form.

The clear problems with my solution above are that
i/ the test is too wide (should be BCB >= 0x0560, AND using STLport, as
well as TESTED_AT) If this is going to be applied in many places I
suggest a new defect macro in borland config.

ii/ forcing _STL::swap means the library will not see the std::swap
specializations. This is not so much a problem when swap is specialized
as an optimization, but will be more of a problem for types that are
swappable but not copyable.

iii/ any other problems that I have missed.

I have not hit problems with any other standard library templates, but
in theory this could apply to any standard algorithm prone to
specialization, such as std::less.

-- 
AlisdairM

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