]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/std/utilities/optional/optional.object/special_members.pass.cpp
Vendor import of libc++ trunk r351319 (just before the release_80
[FreeBSD/FreeBSD.git] / test / std / utilities / optional / optional.object / special_members.pass.cpp
1 //===----------------------------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 // UNSUPPORTED: c++98, c++03, c++11, c++14
11
12 // <optional>
13
14 // Make sure we properly generate special member functions for optional<T>
15 // based on the properties of T itself.
16
17 #include <optional>
18 #include <type_traits>
19
20 #include "archetypes.hpp"
21
22
23 template <class T>
24 struct SpecialMemberTest {
25     using O = std::optional<T>;
26
27     static_assert(std::is_default_constructible_v<O>,
28         "optional is always default constructible.");
29
30     static_assert(std::is_copy_constructible_v<O> == std::is_copy_constructible_v<T>,
31         "optional<T> is copy constructible if and only if T is copy constructible.");
32
33     static_assert(std::is_move_constructible_v<O> ==
34         (std::is_copy_constructible_v<T> || std::is_move_constructible_v<T>),
35         "optional<T> is move constructible if and only if T is copy or move constructible.");
36
37     static_assert(std::is_copy_assignable_v<O> ==
38         (std::is_copy_constructible_v<T> && std::is_copy_assignable_v<T>),
39         "optional<T> is copy assignable if and only if T is both copy "
40         "constructible and copy assignable.");
41
42     static_assert(std::is_move_assignable_v<O> ==
43         ((std::is_move_constructible_v<T> && std::is_move_assignable_v<T>) ||
44          (std::is_copy_constructible_v<T> && std::is_copy_assignable_v<T>)),
45         "optional<T> is move assignable if and only if T is both move constructible and "
46         "move assignable, or both copy constructible and copy assignable.");
47 };
48
49 template <class ...Args> static void sink(Args&&...) {}
50
51 template <class ...TestTypes>
52 struct DoTestsMetafunction {
53     DoTestsMetafunction() { sink(SpecialMemberTest<TestTypes>{}...); }
54 };
55
56 int main() {
57     sink(
58         ImplicitTypes::ApplyTypes<DoTestsMetafunction>{},
59         ExplicitTypes::ApplyTypes<DoTestsMetafunction>{},
60         NonLiteralTypes::ApplyTypes<DoTestsMetafunction>{},
61         NonTrivialTypes::ApplyTypes<DoTestsMetafunction>{}
62     );
63 }