• 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
11 // <optional>
12 
13 
14 #include <optional>
15 #include <type_traits>
16 #include <cassert>
17 
18 #include "archetypes.hpp"
19 
20 template <class T>
21 struct SpecialMemberTest {
22     using O = std::optional<T>;
23 
24     static_assert(std::is_default_constructible_v<O>,
25         "optional is always default constructible.");
26     static_assert(std::is_copy_constructible_v<O> == std::is_copy_constructible_v<T>,
27         "optional<T> is copy constructible if and only if T is copy constructible.");
28     static_assert(std::is_move_constructible_v<O> ==
29         (std::is_copy_constructible_v<T> || std::is_move_constructible_v<T>),
30         "optional<T> is move constructible if and only if T is copy or move constructible.");
31     static_assert(std::is_copy_assignable_v<O> ==
32         (std::is_copy_constructible_v<T> && std::is_copy_assignable_v<T>),
33         "optional<T> is copy assignable if and only if T is both copy "
34         "constructible and copy assignable.");
35     static_assert(std::is_move_assignable_v<O> ==
36         ((std::is_copy_constructible_v<T> && std::is_copy_assignable_v<T>) ||
37          (std::is_move_constructible_v<T> && std::is_move_assignable_v<T>)),
38         "optional<T> is move assignable if and only if T is both move assignable and "
39         "move constructible, or both copy constructible and copy assignable.");
40 };
41 
sink(Args &&...)42 template <class ...Args> static void sink(Args&&...) {}
43 
44 template <class ...TestTypes>
45 struct DoTestsMetafunction {
DoTestsMetafunctionDoTestsMetafunction46     DoTestsMetafunction() { sink(SpecialMemberTest<TestTypes>{}...); }
47 };
48 
49 struct TrivialMoveNonTrivialCopy {
50     TrivialMoveNonTrivialCopy() = default;
TrivialMoveNonTrivialCopyTrivialMoveNonTrivialCopy51     TrivialMoveNonTrivialCopy(const TrivialMoveNonTrivialCopy&) {}
52     TrivialMoveNonTrivialCopy(TrivialMoveNonTrivialCopy&&) = default;
operator =TrivialMoveNonTrivialCopy53     TrivialMoveNonTrivialCopy& operator=(const TrivialMoveNonTrivialCopy&) { return *this; }
54     TrivialMoveNonTrivialCopy& operator=(TrivialMoveNonTrivialCopy&&) = default;
55 };
56 
57 struct TrivialCopyNonTrivialMove {
58     TrivialCopyNonTrivialMove() = default;
59     TrivialCopyNonTrivialMove(const TrivialCopyNonTrivialMove&) = default;
TrivialCopyNonTrivialMoveTrivialCopyNonTrivialMove60     TrivialCopyNonTrivialMove(TrivialCopyNonTrivialMove&&) {}
61     TrivialCopyNonTrivialMove& operator=(const TrivialCopyNonTrivialMove&) = default;
operator =TrivialCopyNonTrivialMove62     TrivialCopyNonTrivialMove& operator=(TrivialCopyNonTrivialMove&&) { return *this; }
63 };
64 
main()65 int main()
66 {
67     sink(
68         ImplicitTypes::ApplyTypes<DoTestsMetafunction>{},
69         ExplicitTypes::ApplyTypes<DoTestsMetafunction>{},
70         NonLiteralTypes::ApplyTypes<DoTestsMetafunction>{},
71         NonTrivialTypes::ApplyTypes<DoTestsMetafunction>{},
72         DoTestsMetafunction<TrivialMoveNonTrivialCopy, TrivialCopyNonTrivialMove>{}
73     );
74 }
75