• 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 
12 // <optional>
13 
14 // Make sure we properly generate special member functions for optional<T>
15 // based on the properties of T itself.
16 
17 #include <optional>
18 #include <type_traits>
19 
20 #include "archetypes.hpp"
21 
22 
23 template <class T>
24 struct SpecialMemberTest {
25     using O = std::optional<T>;
26 
27     static_assert(std::is_default_constructible_v<O>,
28         "optional is always default constructible.");
29 
30     static_assert(std::is_copy_constructible_v<O> == std::is_copy_constructible_v<T>,
31         "optional<T> is copy constructible if and only if T is copy constructible.");
32 
33     static_assert(std::is_move_constructible_v<O> ==
34         (std::is_copy_constructible_v<T> || std::is_move_constructible_v<T>),
35         "optional<T> is move constructible if and only if T is copy or move constructible.");
36 
37     static_assert(std::is_copy_assignable_v<O> ==
38         (std::is_copy_constructible_v<T> && std::is_copy_assignable_v<T>),
39         "optional<T> is copy assignable if and only if T is both copy "
40         "constructible and copy assignable.");
41 
42     static_assert(std::is_move_assignable_v<O> ==
43         ((std::is_move_constructible_v<T> && std::is_move_assignable_v<T>) ||
44          (std::is_copy_constructible_v<T> && std::is_copy_assignable_v<T>)),
45         "optional<T> is move assignable if and only if T is both move constructible and "
46         "move assignable, or both copy constructible and copy assignable.");
47 };
48 
sink(Args &&...)49 template <class ...Args> static void sink(Args&&...) {}
50 
51 template <class ...TestTypes>
52 struct DoTestsMetafunction {
DoTestsMetafunctionDoTestsMetafunction53     DoTestsMetafunction() { sink(SpecialMemberTest<TestTypes>{}...); }
54 };
55 
main()56 int main() {
57     sink(
58         ImplicitTypes::ApplyTypes<DoTestsMetafunction>{},
59         ExplicitTypes::ApplyTypes<DoTestsMetafunction>{},
60         NonLiteralTypes::ApplyTypes<DoTestsMetafunction>{},
61         NonTrivialTypes::ApplyTypes<DoTestsMetafunction>{}
62     );
63 }
64