1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // UNSUPPORTED: c++98, c++03 11 12 // <string> 13 14 // basic_string& operator=(basic_string&& c) 15 // noexcept( 16 // allocator_traits<allocator_type>::propagate_on_container_move_assignment::value || 17 // allocator_traits<allocator_type>::is_always_equal::value); // C++17 18 // 19 // before C++17, we use the conforming extension 20 // noexcept( 21 // allocator_type::propagate_on_container_move_assignment::value && 22 // is_nothrow_move_assignable<allocator_type>::value); 23 24 #include <string> 25 #include <cassert> 26 27 #include "test_macros.h" 28 #include "test_allocator.h" 29 30 template <class T> 31 struct some_alloc 32 { 33 typedef T value_type; 34 some_alloc(const some_alloc&); 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 void deallocate(void*, unsigned) {} 45 46 typedef std::false_type propagate_on_container_move_assignment; 47 typedef std::true_type is_always_equal; 48 }; 49 50 template <class T> 51 struct some_alloc3 52 { 53 typedef T value_type; 54 55 some_alloc3() {} 56 some_alloc3(const some_alloc3&); 57 void deallocate(void*, unsigned) {} 58 59 typedef std::false_type propagate_on_container_move_assignment; 60 typedef std::false_type is_always_equal; 61 }; 62 63 int main() 64 { 65 { 66 typedef std::string C; 67 static_assert(std::is_nothrow_move_assignable<C>::value, ""); 68 } 69 { 70 typedef std::basic_string<char, std::char_traits<char>, test_allocator<char>> C; 71 static_assert(!std::is_nothrow_move_assignable<C>::value, ""); 72 } 73 { 74 typedef std::basic_string<char, std::char_traits<char>, some_alloc<char>> C; 75 #if TEST_STD_VER > 14 76 // if the allocators are always equal, then the move assignment can be noexcept 77 static_assert( std::is_nothrow_move_assignable<C>::value, ""); 78 #else 79 static_assert(!std::is_nothrow_move_assignable<C>::value, ""); 80 #endif 81 } 82 #if TEST_STD_VER > 14 83 { 84 // POCMA is false, always equal 85 typedef std::basic_string<char, std::char_traits<char>, some_alloc2<char>> C; 86 static_assert( std::is_nothrow_move_assignable<C>::value, ""); 87 } 88 { 89 // POCMA is false, not always equal 90 typedef std::basic_string<char, std::char_traits<char>, some_alloc3<char>> C; 91 static_assert(!std::is_nothrow_move_assignable<C>::value, ""); 92 } 93 #endif 94 } 95