]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/std/ranges/adaptors/detail/copyable_box.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / std / ranges / adaptors / detail / copyable_box.cc
1 // Copyright (C) 2020-2023 Free Software Foundation, Inc.
2 //
3 // This file is part of the GNU ISO C++ Library. This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 3, or (at your option)
7 // any later version.
8
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING3. If not see
16 // <http://www.gnu.org/licenses/>.
17
18 // { dg-options "-std=gnu++2a" }
19 // { dg-do compile { target c++2a } }
20
21 #include <ranges>
22
23 using std::ranges::__detail::__box;
24
25 using T = decltype([] { return 0; });
26 static_assert(std::is_empty_v<__box<T>>);
27 static_assert(std::is_nothrow_copy_constructible_v<__box<T>>);
28 static_assert(std::is_nothrow_move_constructible_v<__box<T>>);
29 static_assert(std::is_nothrow_constructible_v<__box<T>, std::in_place_t>);
30 static_assert(requires (__box<T> a) {
31 a = a;
32 a = std::move(a);
33 a.operator*();
34 a.operator->();
35 a.has_value();
36 });
37
38 struct S
39 {
40 S();
41 ~S();
42 S(const S&);
43 S(S&&);
44 S& operator=(const S&);
45 S& operator=(S&&);
46 };
47 static_assert(std::is_empty_v<__box<S>>);
48 static_assert(!std::is_nothrow_copy_constructible_v<__box<S>>
49 && std::is_copy_constructible_v<__box<S>>);
50 static_assert(!std::is_nothrow_move_constructible_v<__box<S>>
51 && std::is_move_constructible_v<__box<S>>);
52 static_assert(!std::is_nothrow_constructible_v<__box<S>, std::in_place_t>
53 && std::is_constructible_v<__box<S>, std::in_place_t>);
54 static_assert(requires (__box<S> a) {
55 a = a;
56 a = std::move(a);
57 a.operator*();
58 a.operator->();
59 a.has_value();
60 });
61
62 using U = decltype([i=0] { return 0; });
63 static_assert(!std::is_empty_v<__box<U>>);
64 static_assert(std::is_nothrow_copy_constructible_v<__box<U>>);
65 static_assert(std::is_nothrow_move_constructible_v<__box<U>>);
66 static_assert(!std::is_nothrow_constructible_v<__box<U>, std::in_place_t>);
67 static_assert(requires (__box<U> a) {
68 a = a;
69 a = std::move(a);
70 a.operator*();
71 a.operator->();
72 a.has_value();
73 });
74
75 constexpr bool
76 test01()
77 {
78 // Verify the default constructor value-initializes the underlying object.
79 __box<int> x;
80 __glibcxx_assert(*x == 0);
81 return true;
82 }
83 static_assert(test01());
84
85 template<bool make_copyable>
86 struct A {
87 A(const A&) = default;
88 A& operator=(const A&) requires make_copyable;
89 A(int, int);
90 A(std::initializer_list<int>) = delete;
91 };
92
93 void
94 test02()
95 {
96 // PR libstdc++/100475
97 static_assert(std::copyable<A<true>>);
98 __box<A<true>> x2(std::in_place, 0, 0);
99
100 static_assert(!std::copyable<A<false>>);
101 __box<A<false>> x1(std::in_place, 0, 0);
102 }
103
104 constexpr bool
105 test03()
106 {
107 // Verify correctness of the non-defaulted operator= for the partial
108 // specialization of __box.
109 struct B {
110 constexpr B(int* p) : p(p) { }
111 constexpr ~B() { ++*p; };
112 B(const B&) = default;
113 B& operator=(const B&) = delete;
114 int* p;
115 };
116 static_assert(!std::copyable<B>);
117 static_assert(std::is_nothrow_copy_constructible_v<B>);
118 static_assert(sizeof(__box<B>) == sizeof(B));
119
120 int m = 0;
121 __box<B> x(std::in_place, &m);
122 __glibcxx_assert(m == 0);
123 x = x;
124 __glibcxx_assert(m == 0);
125 x = std::move(x);
126 __glibcxx_assert(m == 0);
127
128 int n = 0;
129 __box<B> y(std::in_place, &n);
130 auto z = x;
131 x = y;
132 __glibcxx_assert(m == 1);
133 __glibcxx_assert(n == 0);
134 __glibcxx_assert(x->p == &n);
135 __glibcxx_assert(y->p == &n);
136 y = std::move(z);
137 __glibcxx_assert(m == 1);
138 __glibcxx_assert(n == 1);
139 __glibcxx_assert(y->p == &m);
140 __glibcxx_assert(z->p == &m);
141
142 return true;
143 }
144 static_assert(test03());