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 int main(int, char**) 66 { 67 { 68 typedef std::string C; 69 static_assert(std::is_nothrow_move_assignable<C>::value, ""); 70 } 71 { 72 typedef std::basic_string<char, std::char_traits<char>, test_allocator<char>> C; 73 static_assert(!std::is_nothrow_move_assignable<C>::value, ""); 74 } 75 { 76 typedef std::basic_string<char, std::char_traits<char>, some_alloc<char>> C; 77 #if TEST_STD_VER > 14 78 // if the allocators are always equal, then the move assignment can be noexcept 79 static_assert( std::is_nothrow_move_assignable<C>::value, ""); 80 #else 81 static_assert(!std::is_nothrow_move_assignable<C>::value, ""); 82 #endif 83 } 84 #if TEST_STD_VER > 14 85 { 86 // POCMA is false, always equal 87 typedef std::basic_string<char, std::char_traits<char>, some_alloc2<char>> C; 88 static_assert( std::is_nothrow_move_assignable<C>::value, ""); 89 } 90 { 91 // POCMA is false, not always equal 92 typedef std::basic_string<char, std::char_traits<char>, some_alloc3<char>> C; 93 static_assert(!std::is_nothrow_move_assignable<C>::value, ""); 94 } 95 #endif 96 97 return 0; 98 } 99