• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, c++17
11 
12 // <optional>
13 
14 // The following special member functions should propagate the triviality of
15 // the element held in the optional (see P0602R4):
16 //
17 // constexpr optional(const optional& rhs);
18 // constexpr optional(optional&& rhs) noexcept(see below);
19 // constexpr optional<T>& operator=(const optional& rhs);
20 // constexpr optional<T>& operator=(optional&& rhs) noexcept(see below);
21 
22 
23 #include <optional>
24 #include <type_traits>
25 
26 #include "archetypes.hpp"
27 
28 
implies(bool p,bool q)29 constexpr bool implies(bool p, bool q) {
30     return !p || q;
31 }
32 
33 template <class T>
34 struct SpecialMemberTest {
35     using O = std::optional<T>;
36 
37     static_assert(implies(std::is_trivially_copy_constructible_v<T>,
38                           std::is_trivially_copy_constructible_v<O>),
39         "optional<T> is trivially copy constructible if T is trivially copy constructible.");
40 
41     static_assert(implies(std::is_trivially_move_constructible_v<T>,
42                           std::is_trivially_move_constructible_v<O>),
43         "optional<T> is trivially move constructible if T is trivially move constructible");
44 
45     static_assert(implies(std::is_trivially_copy_constructible_v<T> &&
46                           std::is_trivially_copy_assignable_v<T> &&
47                           std::is_trivially_destructible_v<T>,
48 
49                           std::is_trivially_copy_assignable_v<O>),
50         "optional<T> is trivially copy assignable if T is "
51         "trivially copy constructible, "
52         "trivially copy assignable, and "
53         "trivially destructible");
54 
55     static_assert(implies(std::is_trivially_move_constructible_v<T> &&
56                           std::is_trivially_move_assignable_v<T> &&
57                           std::is_trivially_destructible_v<T>,
58 
59                           std::is_trivially_move_assignable_v<O>),
60         "optional<T> is trivially move assignable if T is "
61         "trivially move constructible, "
62         "trivially move assignable, and"
63         "trivially destructible.");
64 };
65 
sink(Args &&...)66 template <class ...Args> static void sink(Args&&...) {}
67 
68 template <class ...TestTypes>
69 struct DoTestsMetafunction {
DoTestsMetafunctionDoTestsMetafunction70     DoTestsMetafunction() { sink(SpecialMemberTest<TestTypes>{}...); }
71 };
72 
73 struct TrivialMoveNonTrivialCopy {
74     TrivialMoveNonTrivialCopy() = default;
TrivialMoveNonTrivialCopyTrivialMoveNonTrivialCopy75     TrivialMoveNonTrivialCopy(const TrivialMoveNonTrivialCopy&) {}
76     TrivialMoveNonTrivialCopy(TrivialMoveNonTrivialCopy&&) = default;
operator =TrivialMoveNonTrivialCopy77     TrivialMoveNonTrivialCopy& operator=(const TrivialMoveNonTrivialCopy&) { return *this; }
78     TrivialMoveNonTrivialCopy& operator=(TrivialMoveNonTrivialCopy&&) = default;
79 };
80 
81 struct TrivialCopyNonTrivialMove {
82     TrivialCopyNonTrivialMove() = default;
83     TrivialCopyNonTrivialMove(const TrivialCopyNonTrivialMove&) = default;
TrivialCopyNonTrivialMoveTrivialCopyNonTrivialMove84     TrivialCopyNonTrivialMove(TrivialCopyNonTrivialMove&&) {}
85     TrivialCopyNonTrivialMove& operator=(const TrivialCopyNonTrivialMove&) = default;
operator =TrivialCopyNonTrivialMove86     TrivialCopyNonTrivialMove& operator=(TrivialCopyNonTrivialMove&&) { return *this; }
87 };
88 
main()89 int main() {
90     sink(
91         ImplicitTypes::ApplyTypes<DoTestsMetafunction>{},
92         ExplicitTypes::ApplyTypes<DoTestsMetafunction>{},
93         NonLiteralTypes::ApplyTypes<DoTestsMetafunction>{},
94         NonTrivialTypes::ApplyTypes<DoTestsMetafunction>{},
95         DoTestsMetafunction<TrivialMoveNonTrivialCopy, TrivialCopyNonTrivialMove>{}
96     );
97 }
98