xref: /llvm-project/libcxx/test/std/containers/sequences/vector/vector.cons/move_assign_noexcept.pass.cpp (revision fb855eb941b6d740cc6560297d0b4d3201dcaf9f)
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 // <vector>
10 
11 // vector& operator=(vector&& c)
12 //     noexcept(
13 //          allocator_type::propagate_on_container_move_assignment::value &&
14 //          is_nothrow_move_assignable<allocator_type>::value);
15 
16 // This tests a conforming extension
17 
18 // UNSUPPORTED: c++03
19 
20 #include <vector>
21 #include <cassert>
22 
23 #include "test_macros.h"
24 #include "MoveOnly.h"
25 #include "test_allocator.h"
26 
27 template <class T>
28 struct some_alloc
29 {
30     typedef T value_type;
31     some_alloc(const some_alloc&);
32     void allocate(std::size_t);
33 };
34 
35 template <class T>
36 struct some_alloc2
37 {
38     typedef T value_type;
39 
some_alloc2some_alloc240     some_alloc2() {}
41     some_alloc2(const some_alloc2&);
42     void allocate(std::size_t);
deallocatesome_alloc243     void deallocate(void*, unsigned) {}
44 
45     typedef std::false_type propagate_on_container_move_assignment;
46     typedef std::true_type is_always_equal;
47 };
48 
49 template <class T>
50 struct some_alloc3
51 {
52     typedef T value_type;
53 
some_alloc3some_alloc354     some_alloc3() {}
55     some_alloc3(const some_alloc3&);
56     void allocate(std::size_t);
deallocatesome_alloc357     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 
main(int,char **)64 int main(int, char**)
65 {
66     {
67         typedef std::vector<MoveOnly> C;
68         static_assert(std::is_nothrow_move_assignable<C>::value, "");
69     }
70     {
71         typedef std::vector<MoveOnly, test_allocator<MoveOnly>> C;
72         static_assert(!std::is_nothrow_move_assignable<C>::value, "");
73     }
74     {
75         typedef std::vector<MoveOnly, other_allocator<MoveOnly>> C;
76         static_assert(std::is_nothrow_move_assignable<C>::value, "");
77     }
78     {
79         typedef std::vector<MoveOnly, some_alloc<MoveOnly>> C;
80     //  In C++17, move assignment for allocators are not allowed to throw
81 #if TEST_STD_VER > 14
82         static_assert( std::is_nothrow_move_assignable<C>::value, "");
83 #else
84         static_assert(!std::is_nothrow_move_assignable<C>::value, "");
85 #endif
86     }
87 
88 #if TEST_STD_VER > 14
89     {  // POCMA false, is_always_equal true
90         typedef std::vector<MoveOnly, some_alloc2<MoveOnly>> C;
91         static_assert( std::is_nothrow_move_assignable<C>::value, "");
92     }
93     {  // POCMA false, is_always_equal false
94         typedef std::vector<MoveOnly, some_alloc3<MoveOnly>> C;
95         static_assert(!std::is_nothrow_move_assignable<C>::value, "");
96     }
97 #endif
98 
99     return 0;
100 }
101