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 T *allocate(size_t); 36 }; 37 38 template <class T> 39 struct some_alloc2 40 { 41 typedef T value_type; 42 43 some_alloc2() {} 44 some_alloc2(const some_alloc2&); 45 T *allocate(size_t); 46 void deallocate(void*, unsigned) {} 47 48 typedef std::false_type propagate_on_container_move_assignment; 49 typedef std::true_type is_always_equal; 50 }; 51 52 template <class T> 53 struct some_alloc3 54 { 55 typedef T value_type; 56 57 some_alloc3() {} 58 some_alloc3(const some_alloc3&); 59 T *allocate(size_t); 60 void deallocate(void*, unsigned) {} 61 62 typedef std::false_type propagate_on_container_move_assignment; 63 typedef std::false_type is_always_equal; 64 }; 65 66 int main() 67 { 68 { 69 typedef std::string C; 70 static_assert(std::is_nothrow_move_assignable<C>::value, ""); 71 } 72 { 73 typedef std::basic_string<char, std::char_traits<char>, test_allocator<char>> C; 74 static_assert(!std::is_nothrow_move_assignable<C>::value, ""); 75 } 76 { 77 typedef std::basic_string<char, std::char_traits<char>, some_alloc<char>> C; 78 #if TEST_STD_VER > 14 79 // if the allocators are always equal, then the move assignment can be noexcept 80 static_assert( std::is_nothrow_move_assignable<C>::value, ""); 81 #else 82 static_assert(!std::is_nothrow_move_assignable<C>::value, ""); 83 #endif 84 } 85 #if TEST_STD_VER > 14 86 { 87 // POCMA is false, always equal 88 typedef std::basic_string<char, std::char_traits<char>, some_alloc2<char>> C; 89 static_assert( std::is_nothrow_move_assignable<C>::value, ""); 90 } 91 { 92 // POCMA is false, not always equal 93 typedef std::basic_string<char, std::char_traits<char>, some_alloc3<char>> C; 94 static_assert(!std::is_nothrow_move_assignable<C>::value, ""); 95 } 96 #endif 97 } 98