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, c++17
13 // The following special member functions should propagate the triviality of
14 // the element held in the optional (see P0602R4):
16 // constexpr optional(const optional& rhs);
17 // constexpr optional(optional&& rhs) noexcept(see below);
18 // constexpr optional<T>& operator=(const optional& rhs);
19 // constexpr optional<T>& operator=(optional&& rhs) noexcept(see below);
23 #include <type_traits>
25 #include "archetypes.h"
27 #include "test_macros.h"
30 constexpr bool implies(bool p
, bool q
) {
35 struct SpecialMemberTest
{
36 using O
= std::optional
<T
>;
38 static_assert(implies(std::is_trivially_copy_constructible_v
<T
>,
39 std::is_trivially_copy_constructible_v
<O
>),
40 "optional<T> is trivially copy constructible if T is trivially copy constructible.");
42 static_assert(implies(std::is_trivially_move_constructible_v
<T
>,
43 std::is_trivially_move_constructible_v
<O
>),
44 "optional<T> is trivially move constructible if T is trivially move constructible");
46 static_assert(implies(std::is_trivially_copy_constructible_v
<T
> &&
47 std::is_trivially_copy_assignable_v
<T
> &&
48 std::is_trivially_destructible_v
<T
>,
50 std::is_trivially_copy_assignable_v
<O
>),
51 "optional<T> is trivially copy assignable if T is "
52 "trivially copy constructible, "
53 "trivially copy assignable, and "
54 "trivially destructible");
56 static_assert(implies(std::is_trivially_move_constructible_v
<T
> &&
57 std::is_trivially_move_assignable_v
<T
> &&
58 std::is_trivially_destructible_v
<T
>,
60 std::is_trivially_move_assignable_v
<O
>),
61 "optional<T> is trivially move assignable if T is "
62 "trivially move constructible, "
63 "trivially move assignable, and"
64 "trivially destructible.");
67 template <class ...Args
> static void sink(Args
&&...) {}
69 template <class ...TestTypes
>
70 struct DoTestsMetafunction
{
71 DoTestsMetafunction() { sink(SpecialMemberTest
<TestTypes
>{}...); }
74 struct TrivialMoveNonTrivialCopy
{
75 TrivialMoveNonTrivialCopy() = default;
76 TrivialMoveNonTrivialCopy(const TrivialMoveNonTrivialCopy
&) {}
77 TrivialMoveNonTrivialCopy(TrivialMoveNonTrivialCopy
&&) = default;
78 TrivialMoveNonTrivialCopy
& operator=(const TrivialMoveNonTrivialCopy
&) { return *this; }
79 TrivialMoveNonTrivialCopy
& operator=(TrivialMoveNonTrivialCopy
&&) = default;
82 struct TrivialCopyNonTrivialMove
{
83 TrivialCopyNonTrivialMove() = default;
84 TrivialCopyNonTrivialMove(const TrivialCopyNonTrivialMove
&) = default;
85 TrivialCopyNonTrivialMove(TrivialCopyNonTrivialMove
&&) {}
86 TrivialCopyNonTrivialMove
& operator=(const TrivialCopyNonTrivialMove
&) = default;
87 TrivialCopyNonTrivialMove
& operator=(TrivialCopyNonTrivialMove
&&) { return *this; }
90 int main(int, char**) {
92 ImplicitTypes::ApplyTypes
<DoTestsMetafunction
>{},
93 ExplicitTypes::ApplyTypes
<DoTestsMetafunction
>{},
94 NonLiteralTypes::ApplyTypes
<DoTestsMetafunction
>{},
95 NonTrivialTypes::ApplyTypes
<DoTestsMetafunction
>{},
96 DoTestsMetafunction
<TrivialMoveNonTrivialCopy
, TrivialCopyNonTrivialMove
>{}