[utility/swap]Call for testing/comments

As discussed previously on the mailing list with David Abrahams and Steve Watanabe, I've written a swap function for boost which uses argument dependent lookup (aka koenig lookup), encapsulating the idiom: using std::swap; swap(a,b); It can currently be found at 'http://www.josephgauterin.myzen.co.uk/swap.zip' as I don't have SVN write access. Currently, I only have access to MSVC8.0 - I'd be grateful if people with access to other compilers could test this (bjam in the test directory), in paticular I believe it may not work correctly with gcc < 3.2 and MSVC6.0. I'd also be grateful for any comments or constructive criticism.

On Wed, 26 Sep 2007, Joseph Gauterin wrote:
As discussed previously on the mailing list with David Abrahams and Steve Watanabe, I've written a swap function for boost which uses argument dependent lookup (aka koenig lookup), encapsulating the idiom:
using std::swap; swap(a,b);
It can currently be found at 'http://www.josephgauterin.myzen.co.uk/swap.zip' as I don't have SVN write access.
Currently, I only have access to MSVC8.0 - I'd be grateful if people with access to other compilers could test this (bjam in the test directory), in paticular I believe it may not work correctly with gcc < 3.2 and MSVC6.0.
I tried with gcc-4.0.2: no problems.
I'd also be grateful for any comments or constructive criticism.
In a few words: I am now already using it ;) -- Francois Duranleau

On Wed, 26 Sep 2007, Joseph Gauterin wrote:
in paticular I believe it may not work correctly with MSVC6.0.
No need to guess there. MSVC6 supports Koenig lookup only for operators, so it most definitely won't work. And there's absolutely nothing that can be done about that, other than finally bringing the code base into
the 21st century. Sebastian Redl

Joseph Gauterin wrote:
As discussed previously on the mailing list with David Abrahams and Steve Watanabe, I've written a swap function for boost which uses argument dependent lookup (aka koenig lookup) [...]
Looks nice! Please note that there's a bug in your test, "specialized_in_std.cpp", as it says: namespace std { void swap(swap_test_class& left, swap_test_class& right) { left.swap(right); } } The C++ Standard does not allow you to add your own overload of swap to the std namespace. Quoting the latest Draft (N2315, [reserved.names]): "It is undefined for a C++ program to add declarations or definitions to namespace std ..." But I guess you know about this already, and you intended to do a template specialization of std::swap, right? Also note that your boost::swap may not work properly on ConceptGCC. I tried the following test program, using the BoostCon Edition of ConceptGCC, from http://www.generic-programming.org/software/ConceptGCC/download.php //////////////////////////////////////////////////////////// #include <boost/utility/swap.hpp> #include <boost/utility.hpp> // Foo is non-copyable, but still it is swappable! class Foo: boost::noncopyable { int m_data; public: Foo() : m_data(0) {} void swap(Foo & arg) { std::swap(this->m_data, arg.m_data); } }; void swap(Foo & arg1, Foo & arg2) { arg1.swap(arg2); } int main(int, char*[]) { Foo object1; Foo object2; boost::swap(object1,object2); return 0; } //////////////////////////////////////////////////////////// In this case, boost::swap should call the swap(Foo &, Foo &) function that I put into the global namespace, right? Instead, ConceptGCC (BoostCon) rejects the program, saying: noncopyable.hpp: In member function 'Foo& Foo::operator=(const Foo&)': noncopyable.hpp:28: error: 'const boost::noncopyable_::noncopyable& boost::noncopyable_::noncopyable::operator=(const boost::noncopyable_::noncopyable&)' is private libs/utility/swap/test/niels_test.cpp:5: error: within this context utility/swap.hpp: At global scope: utility/swap.hpp:20: note: synthesized method 'Foo& Foo::operator=(const Foo&)' first required here Actually Douglas Gregor already has a plan on how to fix this issue: http://conceptgcc.wordpress.com/2007/01/02/revisiting-name-lookup-with-the-s... So I guess in the future your boost::swap will work fine with ConceptGCC as well. :-) Kind regards, Niels -- Niels Dekker http://www.xs4all.nl/~nd/dekkerware Scientific programmer at LKEB, Leiden University Medical Center

I have now uploaded the files the the boost sandbox.
Looks nice! Thanks.
Please note that there's a bug in your test, "specialized_in_std.cpp", The C++ Standard does not allow you to add your own overload of swap to the std namespace...I guess you know about this already, and you intended to do a template specialization of std::swap, right? I've corrected it in the checked in version - thanks for noticing.
Joe Gauterin.

Joseph Gauterin wrote:
I have now uploaded the files the boost sandbox.
So you *do* have SVN write access by now :-)
The C++ Standard does not allow you to add your own overload of swap to the std namespace... I've corrected it in the checked in version - thanks for noticing.
You're welcome. A small remark about sandbox/swap/libs/utility/swap.html. It says: "The alternative to using argument dependent lookup in this situation is to provide a template specialization of std::swap for every type that requires a specialized swap. Although this is legal C++, no boost libraries use this method." Please note that you cannot add a partial template specialization of std::swap. So for instance, boost::shared_ptr<T> cannot have a generic template specialization of std::swap. namespace std { // This is NOT legal C++!!! template <typename T> void swap<boost::shared_ptr<T> >( boost::shared_ptr<T> & a, boost::shared_ptr<T> & b) { a.swap(b); } } This probably explains why boost libraries don't do it like that... BTW, I think it would be nice to add a literature reference to the doc. I would suggest adding a reference to Scott Meyers, Effective C++ Third Edition, Item 25: Consider support for a non-throwing swap. Kind regards, Niels
participants (4)
-
François Duranleau
-
Joseph Gauterin
-
Niels Dekker - mail address until 2008-12-31
-
Sebastian Redl