xref: /llvm-project/libcxx/test/std/containers/sequences/array/array.cons/implicit_copy.pass.cpp (revision 9fb3669429a8bc59622c26ab6f5cf6926ee97e7d)
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 // <array>
10 
11 // implicitly generated array constructors / assignment operators
12 
13 #include <array>
14 #include <type_traits>
15 #include <cassert>
16 #include "test_macros.h"
17 
18 // In C++03 the copy assignment operator is not deleted when the implicitly
19 // generated operator would be ill-formed; like in the case of a struct with a
20 // const member.
21 #if TEST_STD_VER < 11
22 #   define TEST_NOT_COPY_ASSIGNABLE(T) ((void)0)
23 #else
24 #   define TEST_NOT_COPY_ASSIGNABLE(T) static_assert(!std::is_copy_assignable<T>::value, "")
25 #endif
26 
27 struct NoDefault {
NoDefaultNoDefault28     TEST_CONSTEXPR NoDefault(int) { }
29 };
30 
31 struct NonTrivialCopy {
NonTrivialCopyNonTrivialCopy32     TEST_CONSTEXPR NonTrivialCopy() { }
NonTrivialCopyNonTrivialCopy33     TEST_CONSTEXPR NonTrivialCopy(NonTrivialCopy const&) { }
operator =NonTrivialCopy34     TEST_CONSTEXPR_CXX14 NonTrivialCopy& operator=(NonTrivialCopy const&) { return *this; }
35 };
36 
tests()37 TEST_CONSTEXPR_CXX14 bool tests()
38 {
39     {
40         typedef std::array<double, 3> Array;
41         Array array = {1.1, 2.2, 3.3};
42         Array copy = array;
43         copy = array;
44         static_assert(std::is_copy_constructible<Array>::value, "");
45         static_assert(std::is_copy_assignable<Array>::value, "");
46     }
47     {
48         typedef std::array<double const, 3> Array;
49         Array array = {1.1, 2.2, 3.3};
50         Array copy = array; (void)copy;
51         static_assert(std::is_copy_constructible<Array>::value, "");
52         TEST_NOT_COPY_ASSIGNABLE(Array);
53     }
54     {
55         typedef std::array<double, 0> Array;
56         Array array = {};
57         Array copy = array;
58         copy = array;
59         static_assert(std::is_copy_constructible<Array>::value, "");
60         static_assert(std::is_copy_assignable<Array>::value, "");
61     }
62     {
63         // const arrays of size 0 should disable the implicit copy assignment operator.
64         typedef std::array<double const, 0> Array;
65         Array array = {};
66         Array copy = array; (void)copy;
67         static_assert(std::is_copy_constructible<Array>::value, "");
68         TEST_NOT_COPY_ASSIGNABLE(Array);
69     }
70     {
71         typedef std::array<NoDefault, 0> Array;
72         Array array = {};
73         Array copy = array;
74         copy = array;
75         static_assert(std::is_copy_constructible<Array>::value, "");
76         static_assert(std::is_copy_assignable<Array>::value, "");
77     }
78     {
79         typedef std::array<NoDefault const, 0> Array;
80         Array array = {};
81         Array copy = array; (void)copy;
82         static_assert(std::is_copy_constructible<Array>::value, "");
83         TEST_NOT_COPY_ASSIGNABLE(Array);
84     }
85 
86     // Make sure we can implicitly copy a std::array of a non-trivially copyable type
87     {
88         typedef std::array<NonTrivialCopy, 0> Array;
89         Array array = {};
90         Array copy = array;
91         copy = array;
92         static_assert(std::is_copy_constructible<Array>::value, "");
93     }
94     {
95         typedef std::array<NonTrivialCopy, 1> Array;
96         Array array = {};
97         Array copy = array;
98         copy = array;
99         static_assert(std::is_copy_constructible<Array>::value, "");
100     }
101     {
102         typedef std::array<NonTrivialCopy, 2> Array;
103         Array array = {};
104         Array copy = array;
105         copy = array;
106         static_assert(std::is_copy_constructible<Array>::value, "");
107     }
108 
109     return true;
110 }
111 
main(int,char **)112 int main(int, char**)
113 {
114     tests();
115 #if TEST_STD_VER >= 14
116     static_assert(tests(), "");
117 #endif
118     return 0;
119 }
120