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