• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
24 template <class T>
25 struct 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 
sink(Args &&...)50 template <class ...Args> static void sink(Args&&...) {}
51 
52 template <class ...TestTypes>
53 struct DoTestsMetafunction {
DoTestsMetafunctionDoTestsMetafunction54     DoTestsMetafunction() { sink(SpecialMemberTest<TestTypes>{}...); }
55 };
56 
main(int,char **)57 int 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