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 50 template <class ...Args> static void sink(Args&&...) {} 51 52 template <class ...TestTypes> 53 struct DoTestsMetafunction { 54 DoTestsMetafunction() { sink(SpecialMemberTest<TestTypes>{}...); } 55 }; 56 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