1 // { dg-do compile { target c++17 }  }
2 
3 // Copyright (C) 2018-2021 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING3.  If not see
18 // <http://www.gnu.org/licenses/>.
19 
20 #include <optional>
21 
22 struct X
23 {
24   ~X();
25 };
26 
27 struct Y
28 {
29   Y& operator=(const Y&) = default;
30   Y& operator=(Y&&);
31   Y(const Y&) = default;
32   Y(Y&&) = default;
33 };
34 
35 struct Z
36 {
37   Z& operator=(const Z&);
38   Z& operator=(Z&&) = default;
39   Z(const Z&) = default;
40 };
41 
42 struct Y2
43 {
44   Y2& operator=(const Y2&) = default;
45   Y2& operator=(Y2&&);
46 };
47 
48 struct Z2
49 {
50   Z2& operator=(const Z2&);
51   Z2& operator=(Z2&&) = default;
52 };
53 
54 static_assert(std::is_trivially_copy_assignable_v<std::optional<int>>);
55 static_assert(std::is_trivially_move_assignable_v<std::optional<int>>);
56 static_assert(!std::is_trivially_copy_assignable_v<std::optional<X>>);
57 static_assert(!std::is_trivially_move_assignable_v<std::optional<X>>);
58 static_assert(std::is_trivially_copy_assignable_v<std::optional<Y>>);
59 static_assert(!std::is_trivially_move_assignable_v<std::optional<Y>>);
60 static_assert(!std::is_trivially_copy_assignable_v<std::optional<Z>>);
61 static_assert(std::is_trivially_move_assignable_v<std::optional<Z>>);
62 static_assert(std::is_trivially_copy_assignable_v<Y2>);
63 static_assert(!std::is_trivially_move_assignable_v<Y2>);
64 static_assert(!std::is_trivially_copy_assignable_v<std::optional<Y2>>);
65 static_assert(!std::is_trivially_move_assignable_v<std::optional<Y2>>);
66 static_assert(!std::is_trivially_copy_assignable_v<Z2>);
67 static_assert(std::is_trivially_move_assignable_v<Z2>);
68 static_assert(!std::is_trivially_copy_assignable_v<std::optional<Z2>>);
69 static_assert(!std::is_trivially_move_assignable_v<std::optional<Z2>>);
70 
71 
72 struct S {
73   S(const S&&) = delete;
74   S& operator=(const S&) = default;
75 };
76 static_assert(std::is_trivially_copy_assignable_v<S>);
77 
78 union U {
79   char dummy;
80   S s;
81 };
82 static_assert(std::is_trivially_copy_assignable_v<U>);
83 
84 static_assert(!std::is_trivially_copy_assignable_v<std::optional<S>>);
85 static_assert(!std::is_copy_assignable_v<std::optional<S>>);
86 
87 struct S2 {
88   S2(S2&&) = delete;
89   S2& operator=(const S2&) = default;
90 };
91 static_assert(std::is_trivially_move_assignable_v<S2>);
92 
93 struct S3 {
94   S3(const S3&);
95   S3& operator=(const S3&) = default;
96 };
97 static_assert(std::is_trivially_copy_assignable_v<S3>);
98 static_assert(std::is_copy_assignable_v<S3>);
99 static_assert(!std::is_trivially_copy_assignable_v<std::optional<S3>>);
100 static_assert(std::is_copy_assignable_v<std::optional<S3>>);
101 
102 struct S4 {
103   S4(S4&&);
104   S4& operator=(S4&&) = default;
105 };
106 static_assert(std::is_trivially_move_assignable_v<S4>);
107 static_assert(std::is_move_assignable_v<S4>);
108 static_assert(!std::is_trivially_move_assignable_v<std::optional<S4>>);
109 static_assert(std::is_move_assignable_v<std::optional<S4>>);
110 
111 union U2 {
112   char dummy;
113   S2 s;
114 };
115 static_assert(std::is_trivially_move_assignable_v<U2>);
116 
117 static_assert(!std::is_trivially_move_assignable_v<std::optional<S2>>);
118 static_assert(!std::is_move_assignable_v<std::optional<S2>>);
119