1 //===----------------------------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // UNSUPPORTED: c++98, c++03, c++11, c++14
14 // Make sure we properly generate special member functions for optional<T>
15 // based on the properties of T itself.
18 #include <type_traits>
20 #include "archetypes.hpp"
24 struct SpecialMemberTest {
25 using O = std::optional<T>;
27 static_assert(std::is_default_constructible_v<O>,
28 "optional is always default constructible.");
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.");
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.");
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.");
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.");
49 template <class ...Args> static void sink(Args&&...) {}
51 template <class ...TestTypes>
52 struct DoTestsMetafunction {
53 DoTestsMetafunction() { sink(SpecialMemberTest<TestTypes>{}...); }
58 ImplicitTypes::ApplyTypes<DoTestsMetafunction>{},
59 ExplicitTypes::ApplyTypes<DoTestsMetafunction>{},
60 NonLiteralTypes::ApplyTypes<DoTestsMetafunction>{},
61 NonTrivialTypes::ApplyTypes<DoTestsMetafunction>{}