|
Boost : |
From: John Maddock (john_at_[hidden])
Date: 2003-09-09 06:54:11
It seems to me that this may be of interest here as well:
> To: C++ libraries mailing list
> Message c++std-lib-11916
>
> Unless I've missed it, we seem to be no further forward in solving the
"swap
> problem" - namely is it permitted to provide user defined overloads of
> std::swap in namespace std?
>
> I don't want to rehearse the old arguments again here, but instead ask a
> different question: what would happen if std::swap were omnipotent and
just
> simply "knows" whether a type has a member function swap or not.
std::swap
> could now be implemented to call the member swap if it were available,
> otherwise to fall back on the slow but safe copy based swap.
>
> The interesting thing is, this is actually implementable right now within
> the current language - I've attached a sample implementation to the end of
> this message, hopefully it really is legal code, although I admit that
only
> one of the three compilers I've tried (VC7.1) would compile it....
>
> Anyway, maybe some food for thought,
>
> regards,
>
> John Maddock
>
> Code follows:
>
> #include <list>
>
> namespace omni{
>
> template <class T, T val>
> struct member_wrapper{};
>
> template <class T>
> char test_for_swap(const T&, member_wrapper<void (T::*)(T&), &T::swap>* p
=
> 0);
>
> template <class T>
> double test_for_swap(const T&, ...);
>
> template <class T>
> struct has_member_swap
> {
> static T t;
> static const bool value =
> (1 == sizeof(test_for_swap(t)));
> };
>
> //BOOST_STATIC_ASSERT(has_member_swap<std::list<int> >::value);
> //BOOST_STATIC_ASSERT(!has_member_swap<int>::value);
> //BOOST_STATIC_ASSERT(!has_member_swap<noswap>::value);
>
> template<bool b>
> struct swapper
> {
> template <class T>
> static void swap(T& t1, T& t2)
> { std::swap(t1, t2); }
> };
>
> template<>
> struct swapper<true>
> {
> template <class T>
> static void swap(T& t1, T& t2)
> { t1.swap(t2); }
> };
>
> template <class T>
> void swap(T& t1, T& t2)
> {
> swapper<has_member_swap<T>::value>::swap(t1, t2);
> }
>
> } // namespace omni
>
> struct noswap{};
>
> int main()
> {
> std::list<int> l1, l2;
> omni::swap(l1, l2);
> noswap s1, s2;
> omni::swap(s1, s2);
> int i1, i2;
> omni::swap(i1, i2);
> return 0;
> }
>
>
>
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk