mclow.lists added a reviewer: EricWF.
mclow.lists added a subscriber: cfe-commits.
Update the noexcept-ness of move-construction and move-assignment for
`basic_string`. Use the new "is_always_equal" type trait for noexcept stuff
when we're building with C++17. Preserve the conforming extension that we had
before for C++14 and before.
Note that in C++17, if POCMA is true, then move-assigning an allocator cannot
throw an exception.
http://reviews.llvm.org/D10963
Files:
include/string
test/std/strings/basic.string/string.cons/move_assign_noexcept.pass.cpp
test/std/strings/basic.string/string.modifiers/string_swap/swap.pass.cpp
Index: test/std/strings/basic.string/string.modifiers/string_swap/swap.pass.cpp
===================================================================
--- test/std/strings/basic.string/string.modifiers/string_swap/swap.pass.cpp
+++ test/std/strings/basic.string/string.modifiers/string_swap/swap.pass.cpp
@@ -10,18 +10,27 @@
// <string>
// void swap(basic_string& s);
-
+// noexcept(allocator_traits<Allocator>::propogate_on_container_swap::value ||
+// allocator_traits<Allocator>::is_always_equal::value); // C++17
+// before C++17, we used:
+// noexcept(!allocator_type::propagate_on_container_swap::value ||
+// __is_nothrow_swappable<allocator_type>::value)
+
#include <string>
#include <stdexcept>
#include <algorithm>
#include <cassert>
+#include "test_macros.h"
#include "min_allocator.h"
template <class S>
void
test(S s1, S s2)
{
+#if TEST_STD_VER > 14
+ static_assert(std::__is_nothrow_swappable<S>::value, "");
+#endif
S s1_ = s1;
S s2_ = s2;
s1.swap(s2);
@@ -52,7 +61,7 @@
test(S("abcdefghijklmnopqrst"), S("1234567890"));
test(S("abcdefghijklmnopqrst"), S("12345678901234567890"));
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
test(S(""), S(""));
Index: test/std/strings/basic.string/string.cons/move_assign_noexcept.pass.cpp
===================================================================
--- test/std/strings/basic.string/string.cons/move_assign_noexcept.pass.cpp
+++ test/std/strings/basic.string/string.cons/move_assign_noexcept.pass.cpp
@@ -11,14 +11,18 @@
// basic_string& operator=(basic_string&& c)
// noexcept(
-// allocator_type::propagate_on_container_move_assignment::value &&
-// is_nothrow_move_assignable<allocator_type>::value);
+// allocator_traits<allocator_type>::propagate_on_container_move_assignment::value ||
+// allocator_traits<allocator_type>::is_always_equal::value); // C++17
+//
+// before C++17, we use the conforming extension
+// noexcept(
+// allocator_type::propagate_on_container_move_assignment::value &&
+// is_nothrow_move_assignable<allocator_type>::value);
-// This tests a conforming extension
-
#include <string>
#include <cassert>
+#include "test_macros.h"
#include "test_allocator.h"
template <class T>
@@ -41,7 +45,11 @@
}
{
typedef std::basic_string<char, std::char_traits<char>, some_alloc<char>> C;
+#if TEST_STD_VER <= 14
static_assert(!std::is_nothrow_move_assignable<C>::value, "");
+#else
+ static_assert( std::is_nothrow_move_assignable<C>::value, "");
+#endif
}
#endif
}
Index: include/string
===================================================================
--- include/string
+++ include/string
@@ -115,8 +115,8 @@
basic_string& operator=(const basic_string& str);
basic_string& operator=(basic_string&& str)
noexcept(
- allocator_type::propagate_on_container_move_assignment::value &&
- is_nothrow_move_assignable<allocator_type>::value);
+ allocator_traits<allocator_type>::propagate_on_container_move_assignment::value ||
+ allocator_traits<allocator_type>::is_always_equal::value); // C++17
basic_string& operator=(const value_type* s);
basic_string& operator=(value_type c);
basic_string& operator=(initializer_list<value_type>);
@@ -1377,9 +1377,14 @@
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
_LIBCPP_INLINE_VISIBILITY
basic_string& operator=(basic_string&& __str)
- _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
- is_nothrow_move_assignable<allocator_type>::value);
+ _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value
+#if _LIBCPP_STD_VER <= 14
+ && is_nothrow_move_assignable<allocator_type>::value
+#else
+ || __alloc_traits::is_always_equal::value
#endif
+ );
+#endif
_LIBCPP_INLINE_VISIBILITY basic_string& operator=(const value_type* __s) {return assign(__s);}
basic_string& operator=(value_type __c);
#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
@@ -1841,11 +1846,16 @@
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
_LIBCPP_INLINE_VISIBILITY
- void __move_assign(basic_string& __str, false_type);
+ void __move_assign(basic_string& __str, false_type)
+ _NOEXCEPT_(__alloc_traits::is_always_equal::value);
_LIBCPP_INLINE_VISIBILITY
void __move_assign(basic_string& __str, true_type)
+#if _LIBCPP_STD_VER <= 14
_NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
+#else
+ _NOEXCEPT;
#endif
+#endif
_LIBCPP_INLINE_VISIBILITY
void
@@ -2439,6 +2449,7 @@
inline _LIBCPP_INLINE_VISIBILITY
void
basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, false_type)
+ _NOEXCEPT_(__alloc_traits::is_always_equal::value)
{
if (__alloc() != __str.__alloc())
assign(__str);
@@ -2450,7 +2461,11 @@
inline _LIBCPP_INLINE_VISIBILITY
void
basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type)
+#if _LIBCPP_STD_VER <= 14
_NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
+#else
+ _NOEXCEPT
+#endif
{
clear();
shrink_to_fit();
@@ -2463,8 +2478,13 @@
inline _LIBCPP_INLINE_VISIBILITY
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::operator=(basic_string&& __str)
- _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
- is_nothrow_move_assignable<allocator_type>::value)
+ _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value
+#if _LIBCPP_STD_VER <= 14
+ && is_nothrow_move_assignable<allocator_type>::value
+#else
+ || __alloc_traits::is_always_equal::value
+#endif
+ )
{
__move_assign(__str, integral_constant<bool,
__alloc_traits::propagate_on_container_move_assignment::value>());
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits