1//===----------------------------------------------------------------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
9// UNSUPPORTED: c++03, c++11, c++14
10
11// <optional>
12
13// Make sure we properly generate special member functions for optional<T>
14// based on the properties of T itself.
15
16#include <optional>
17#include <type_traits>
18
19#include "archetypes.h"
20
21#include "test_macros.h"
22
23
24template <class T>
25struct SpecialMemberTest {
26 using O = std::optional<T>;
27
28 static_assert(std::is_default_constructible_v<O>,
29 "optional is always default constructible.");
30
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.");
33
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.");
37
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.");
42
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.");
48};
49
50template <class ...Args> static void sink(Args&&...) {}
51
52template <class ...TestTypes>
53struct DoTestsMetafunction {
54 DoTestsMetafunction() { sink(SpecialMemberTest<TestTypes>{}...); }
55};
56
57int main(int, char**) {
58 sink(
59 ImplicitTypes::ApplyTypes<DoTestsMetafunction>{},
60 ExplicitTypes::ApplyTypes<DoTestsMetafunction>{},
61 NonLiteralTypes::ApplyTypes<DoTestsMetafunction>{},
62 NonTrivialTypes::ApplyTypes<DoTestsMetafunction>{}
63 );
64 return 0;
65}
66

source code of libcxx/test/std/utilities/optional/optional.object/special_members.pass.cpp