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