159cdf90aSEric Fiselier //===----------------------------------------------------------------------===//
259cdf90aSEric Fiselier //
357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
659cdf90aSEric Fiselier //
759cdf90aSEric Fiselier //===----------------------------------------------------------------------===//
859cdf90aSEric Fiselier
959cdf90aSEric Fiselier // <array>
1059cdf90aSEric Fiselier
1159cdf90aSEric Fiselier // implicitly generated array constructors / assignment operators
1259cdf90aSEric Fiselier
1359cdf90aSEric Fiselier #include <array>
1459cdf90aSEric Fiselier #include <type_traits>
1559cdf90aSEric Fiselier #include <cassert>
1659cdf90aSEric Fiselier #include "test_macros.h"
1759cdf90aSEric Fiselier
1859cdf90aSEric Fiselier // In C++03 the copy assignment operator is not deleted when the implicitly
1959cdf90aSEric Fiselier // generated operator would be ill-formed; like in the case of a struct with a
2059cdf90aSEric Fiselier // const member.
2159cdf90aSEric Fiselier #if TEST_STD_VER < 11
2259cdf90aSEric Fiselier # define TEST_NOT_COPY_ASSIGNABLE(T) ((void)0)
2359cdf90aSEric Fiselier #else
2459cdf90aSEric Fiselier # define TEST_NOT_COPY_ASSIGNABLE(T) static_assert(!std::is_copy_assignable<T>::value, "")
2559cdf90aSEric Fiselier #endif
2659cdf90aSEric Fiselier
2759cdf90aSEric Fiselier struct NoDefault {
NoDefaultNoDefault2877b9abfcSLouis Dionne TEST_CONSTEXPR NoDefault(int) { }
2959cdf90aSEric Fiselier };
3059cdf90aSEric Fiselier
31*7265ff92SLouis Dionne struct NonTrivialCopy {
NonTrivialCopyNonTrivialCopy32*7265ff92SLouis Dionne TEST_CONSTEXPR NonTrivialCopy() { }
NonTrivialCopyNonTrivialCopy33*7265ff92SLouis Dionne TEST_CONSTEXPR NonTrivialCopy(NonTrivialCopy const&) { }
operator =NonTrivialCopy34*7265ff92SLouis Dionne TEST_CONSTEXPR_CXX14 NonTrivialCopy& operator=(NonTrivialCopy const&) { return *this; }
35*7265ff92SLouis Dionne };
36*7265ff92SLouis Dionne
tests()3777b9abfcSLouis Dionne TEST_CONSTEXPR_CXX14 bool tests()
3877b9abfcSLouis Dionne {
3959cdf90aSEric Fiselier {
40*7265ff92SLouis Dionne typedef std::array<double, 3> Array;
41*7265ff92SLouis Dionne Array array = {1.1, 2.2, 3.3};
42*7265ff92SLouis Dionne Array copy = array;
43*7265ff92SLouis Dionne copy = array;
44*7265ff92SLouis Dionne static_assert(std::is_copy_constructible<Array>::value, "");
45*7265ff92SLouis Dionne static_assert(std::is_copy_assignable<Array>::value, "");
4659cdf90aSEric Fiselier }
4759cdf90aSEric Fiselier {
48*7265ff92SLouis Dionne typedef std::array<double const, 3> Array;
49*7265ff92SLouis Dionne Array array = {1.1, 2.2, 3.3};
50*7265ff92SLouis Dionne Array copy = array; (void)copy;
51*7265ff92SLouis Dionne static_assert(std::is_copy_constructible<Array>::value, "");
52*7265ff92SLouis Dionne TEST_NOT_COPY_ASSIGNABLE(Array);
5359cdf90aSEric Fiselier }
5459cdf90aSEric Fiselier {
55*7265ff92SLouis Dionne typedef std::array<double, 0> Array;
56*7265ff92SLouis Dionne Array array = {};
57*7265ff92SLouis Dionne Array copy = array;
58*7265ff92SLouis Dionne copy = array;
59*7265ff92SLouis Dionne static_assert(std::is_copy_constructible<Array>::value, "");
60*7265ff92SLouis Dionne static_assert(std::is_copy_assignable<Array>::value, "");
6159cdf90aSEric Fiselier }
6259cdf90aSEric Fiselier {
6359cdf90aSEric Fiselier // const arrays of size 0 should disable the implicit copy assignment operator.
64*7265ff92SLouis Dionne typedef std::array<double const, 0> Array;
65*7265ff92SLouis Dionne Array array = {};
66*7265ff92SLouis Dionne Array copy = array; (void)copy;
67*7265ff92SLouis Dionne static_assert(std::is_copy_constructible<Array>::value, "");
68*7265ff92SLouis Dionne TEST_NOT_COPY_ASSIGNABLE(Array);
6959cdf90aSEric Fiselier }
7059cdf90aSEric Fiselier {
71*7265ff92SLouis Dionne typedef std::array<NoDefault, 0> Array;
72*7265ff92SLouis Dionne Array array = {};
73*7265ff92SLouis Dionne Array copy = array;
74*7265ff92SLouis Dionne copy = array;
75*7265ff92SLouis Dionne static_assert(std::is_copy_constructible<Array>::value, "");
76*7265ff92SLouis Dionne static_assert(std::is_copy_assignable<Array>::value, "");
7759cdf90aSEric Fiselier }
7859cdf90aSEric Fiselier {
79*7265ff92SLouis Dionne typedef std::array<NoDefault const, 0> Array;
80*7265ff92SLouis Dionne Array array = {};
81*7265ff92SLouis Dionne Array copy = array; (void)copy;
82*7265ff92SLouis Dionne static_assert(std::is_copy_constructible<Array>::value, "");
83*7265ff92SLouis Dionne TEST_NOT_COPY_ASSIGNABLE(Array);
84*7265ff92SLouis Dionne }
85*7265ff92SLouis Dionne
86*7265ff92SLouis Dionne // Make sure we can implicitly copy a std::array of a non-trivially copyable type
87*7265ff92SLouis Dionne {
88*7265ff92SLouis Dionne typedef std::array<NonTrivialCopy, 0> Array;
89*7265ff92SLouis Dionne Array array = {};
90*7265ff92SLouis Dionne Array copy = array;
91*7265ff92SLouis Dionne copy = array;
92*7265ff92SLouis Dionne static_assert(std::is_copy_constructible<Array>::value, "");
93*7265ff92SLouis Dionne }
94*7265ff92SLouis Dionne {
95*7265ff92SLouis Dionne typedef std::array<NonTrivialCopy, 1> Array;
96*7265ff92SLouis Dionne Array array = {};
97*7265ff92SLouis Dionne Array copy = array;
98*7265ff92SLouis Dionne copy = array;
99*7265ff92SLouis Dionne static_assert(std::is_copy_constructible<Array>::value, "");
100*7265ff92SLouis Dionne }
101*7265ff92SLouis Dionne {
102*7265ff92SLouis Dionne typedef std::array<NonTrivialCopy, 2> Array;
103*7265ff92SLouis Dionne Array array = {};
104*7265ff92SLouis Dionne Array copy = array;
105*7265ff92SLouis Dionne copy = array;
106*7265ff92SLouis Dionne static_assert(std::is_copy_constructible<Array>::value, "");
10759cdf90aSEric Fiselier }
10859cdf90aSEric Fiselier
10977b9abfcSLouis Dionne return true;
11077b9abfcSLouis Dionne }
1112df59c50SJF Bastien
main(int,char **)11277b9abfcSLouis Dionne int main(int, char**)
11377b9abfcSLouis Dionne {
11477b9abfcSLouis Dionne tests();
11577b9abfcSLouis Dionne #if TEST_STD_VER >= 14
11677b9abfcSLouis Dionne static_assert(tests(), "");
11777b9abfcSLouis Dionne #endif
1182df59c50SJF Bastien return 0;
11959cdf90aSEric Fiselier }
120