1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14
13 // Make sure we properly generate special member functions for optional<T>
14 // based on the properties of T itself.
17 #include <type_traits>
19 #include "archetypes.h"
21 #include "test_macros.h"
25 struct SpecialMemberTest
{
26 using O
= std::optional
<T
>;
28 static_assert(std::is_default_constructible_v
<O
>,
29 "optional is always default constructible.");
31 static_assert(std::is_copy_constructible_v
<O
> == std::is_copy_constructible_v
<T
>,
32 "optional<T> is copy constructible if and only if T is copy constructible.");
34 static_assert(std::is_move_constructible_v
<O
> ==
35 (std::is_copy_constructible_v
<T
> || std::is_move_constructible_v
<T
>),
36 "optional<T> is move constructible if and only if T is copy or move constructible.");
38 static_assert(std::is_copy_assignable_v
<O
> ==
39 (std::is_copy_constructible_v
<T
> && std::is_copy_assignable_v
<T
>),
40 "optional<T> is copy assignable if and only if T is both copy "
41 "constructible and copy assignable.");
43 static_assert(std::is_move_assignable_v
<O
> ==
44 ((std::is_move_constructible_v
<T
> && std::is_move_assignable_v
<T
>) ||
45 (std::is_copy_constructible_v
<T
> && std::is_copy_assignable_v
<T
>)),
46 "optional<T> is move assignable if and only if T is both move constructible and "
47 "move assignable, or both copy constructible and copy assignable.");
50 template <class ...Args
> static void sink(Args
&&...) {}
52 template <class ...TestTypes
>
53 struct DoTestsMetafunction
{
54 DoTestsMetafunction() { sink(SpecialMemberTest
<TestTypes
>{}...); }
57 int main(int, char**) {
59 ImplicitTypes::ApplyTypes
<DoTestsMetafunction
>{},
60 ExplicitTypes::ApplyTypes
<DoTestsMetafunction
>{},
61 NonLiteralTypes::ApplyTypes
<DoTestsMetafunction
>{},
62 NonTrivialTypes::ApplyTypes
<DoTestsMetafunction
>{}