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
sink(Args &&...)49 template <class ...Args> static void sink(Args&&...) {}
50
51 template <class ...TestTypes>
52 struct DoTestsMetafunction {
DoTestsMetafunctionDoTestsMetafunction53 DoTestsMetafunction() { sink(SpecialMemberTest<TestTypes>{}...); }
54 };
55
main()56 int main() {
57 sink(
58 ImplicitTypes::ApplyTypes<DoTestsMetafunction>{},
59 ExplicitTypes::ApplyTypes<DoTestsMetafunction>{},
60 NonLiteralTypes::ApplyTypes<DoTestsMetafunction>{},
61 NonTrivialTypes::ApplyTypes<DoTestsMetafunction>{}
62 );
63 }
64