1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // UNSUPPORTED: c++03 10 11 // <string> 12 13 // basic_string& operator=(basic_string&& c) 14 // noexcept( 15 // allocator_traits<allocator_type>::propagate_on_container_move_assignment::value || 16 // allocator_traits<allocator_type>::is_always_equal::value); // C++17 17 // 18 // before C++17, we use the conforming extension 19 // noexcept( 20 // allocator_type::propagate_on_container_move_assignment::value && 21 // is_nothrow_move_assignable<allocator_type>::value); 22 23 #include <string> 24 #include <cassert> 25 26 #include "test_macros.h" 27 #include "test_allocator.h" 28 29 template <class T> 30 struct some_alloc 31 { 32 typedef T value_type; 33 some_alloc(const some_alloc&); 34 T *allocate(size_t); 35 }; 36 37 template <class T> 38 struct some_alloc2 39 { 40 typedef T value_type; 41 42 some_alloc2() {} 43 some_alloc2(const some_alloc2&); 44 T *allocate(size_t); 45 void deallocate(void*, unsigned) {} 46 47 typedef std::false_type propagate_on_container_move_assignment; 48 typedef std::true_type is_always_equal; 49 }; 50 51 template <class T> 52 struct some_alloc3 53 { 54 typedef T value_type; 55 56 some_alloc3() {} 57 some_alloc3(const some_alloc3&); 58 T *allocate(size_t); 59 void deallocate(void*, unsigned) {} 60 61 typedef std::false_type propagate_on_container_move_assignment; 62 typedef std::false_type is_always_equal; 63 }; 64 65 bool test() { 66 { 67 typedef std::string C; 68 static_assert(std::is_nothrow_move_assignable<C>::value, ""); 69 } 70 { 71 typedef std::basic_string<char, std::char_traits<char>, test_allocator<char>> C; 72 static_assert(!std::is_nothrow_move_assignable<C>::value, ""); 73 } 74 { 75 typedef std::basic_string<char, std::char_traits<char>, some_alloc<char>> C; 76 #if TEST_STD_VER > 14 77 // if the allocators are always equal, then the move assignment can be noexcept 78 static_assert( std::is_nothrow_move_assignable<C>::value, ""); 79 #else 80 static_assert(!std::is_nothrow_move_assignable<C>::value, ""); 81 #endif 82 } 83 #if TEST_STD_VER > 14 84 { 85 // POCMA is false, always equal 86 typedef std::basic_string<char, std::char_traits<char>, some_alloc2<char>> C; 87 static_assert( std::is_nothrow_move_assignable<C>::value, ""); 88 } 89 { 90 // POCMA is false, not always equal 91 typedef std::basic_string<char, std::char_traits<char>, some_alloc3<char>> C; 92 static_assert(!std::is_nothrow_move_assignable<C>::value, ""); 93 } 94 #endif 95 96 return true; 97 } 98 99 int main(int, char**) 100 { 101 test(); 102 #if TEST_STD_VER > 17 103 // static_assert(test()); 104 #endif 105 106 return 0; 107 } 108