This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[v3 patch] Use std::__is_nothrow_swappable in __alloc_traits::_S_nothrow_swap()


This fixes a bug in _S_nothrow_swap(), where I assumed that allocator
types are always swappable, but they don't need to be if
propagate_on_container_swap is false. Thanks to Ville's new trait it's
easy to fix.

For the branches we don't have __is_nothrow_swappable, but could
dispatch on the propagation trait so we only test if swapping throws
when we're actually going to swap. However, I'm not sure if
_S_nothrow_swap() is actually worth keeping, because the standard says
that for allocators that propagate on swap, they shall be swappable
and swapping them shall not throw exceptions.

This means the current code is doubly-wrong, it assumes allocators are
always swappable (not required to be true) and then tests whether
swapping them will throw (if they're swappable swapping must not
throw).

So we could remove all uses of _Alloc_traits::_S_nothrow_swap() and
make containers' swap() members unconditionally noexcept. The only
reason to keep _S_nothrow_swap is if we want to support allocators
with throwing swaps as an extension.  Thoughts?

For now I'm committing this to trunk, tested powerpc64le-linux.
commit e43ff136f29ca61fc6277fbef7505445c948bf55
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Jun 17 11:25:13 2015 +0100

    	* include/ext/alloc_traits.h (__alloc_traits::_S_nothrow_swap()): Use
    	__is_nothrow_swappable.

diff --git a/libstdc++-v3/include/ext/alloc_traits.h b/libstdc++-v3/include/ext/alloc_traits.h
index 06bc70a..bd0f759 100644
--- a/libstdc++-v3/include/ext/alloc_traits.h
+++ b/libstdc++-v3/include/ext/alloc_traits.h
@@ -159,9 +159,8 @@ template<typename _Alloc>
 
     static constexpr bool _S_nothrow_swap()
     {
-      using std::swap;
       return !_S_propagate_on_swap()
-       	|| noexcept(swap(std::declval<_Alloc&>(), std::declval<_Alloc&>()));
+	|| std::__is_nothrow_swappable<_Alloc>::value;
     }
 
     template<typename _Tp>

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]