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// <optional> 12 13 14#include <optional> 15#include <type_traits> 16#include <cassert> 17 18#include "archetypes.hpp" 19 20template <class T> 21struct SpecialMemberTest { 22 using O = std::optional<T>; 23 24 static_assert(std::is_default_constructible_v<O>, 25 "optional is always default constructible."); 26 static_assert(std::is_copy_constructible_v<O> == std::is_copy_constructible_v<T>, 27 "optional<T> is copy constructible if and only if T is copy constructible."); 28 static_assert(std::is_move_constructible_v<O> == 29 (std::is_copy_constructible_v<T> || std::is_move_constructible_v<T>), 30 "optional<T> is move constructible if and only if T is copy or move constructible."); 31 static_assert(std::is_copy_assignable_v<O> == 32 (std::is_copy_constructible_v<T> && std::is_copy_assignable_v<T>), 33 "optional<T> is copy assignable if and only if T is both copy " 34 "constructible and copy assignable."); 35 static_assert(std::is_move_assignable_v<O> == 36 ((std::is_copy_constructible_v<T> && std::is_copy_assignable_v<T>) || 37 (std::is_move_constructible_v<T> && std::is_move_assignable_v<T>)), 38 "optional<T> is move assignable if and only if T is both move assignable and " 39 "move constructible, or both copy constructible and copy assignable."); 40}; 41 42template <class ...Args> static void sink(Args&&...) {} 43 44template <class ...TestTypes> 45struct DoTestsMetafunction { 46 DoTestsMetafunction() { sink(SpecialMemberTest<TestTypes>{}...); } 47}; 48 49struct TrivialMoveNonTrivialCopy { 50 TrivialMoveNonTrivialCopy() = default; 51 TrivialMoveNonTrivialCopy(const TrivialMoveNonTrivialCopy&) {} 52 TrivialMoveNonTrivialCopy(TrivialMoveNonTrivialCopy&&) = default; 53 TrivialMoveNonTrivialCopy& operator=(const TrivialMoveNonTrivialCopy&) { return *this; } 54 TrivialMoveNonTrivialCopy& operator=(TrivialMoveNonTrivialCopy&&) = default; 55}; 56 57struct TrivialCopyNonTrivialMove { 58 TrivialCopyNonTrivialMove() = default; 59 TrivialCopyNonTrivialMove(const TrivialCopyNonTrivialMove&) = default; 60 TrivialCopyNonTrivialMove(TrivialCopyNonTrivialMove&&) {} 61 TrivialCopyNonTrivialMove& operator=(const TrivialCopyNonTrivialMove&) = default; 62 TrivialCopyNonTrivialMove& operator=(TrivialCopyNonTrivialMove&&) { return *this; } 63}; 64 65int main() 66{ 67 sink( 68 ImplicitTypes::ApplyTypes<DoTestsMetafunction>{}, 69 ExplicitTypes::ApplyTypes<DoTestsMetafunction>{}, 70 NonLiteralTypes::ApplyTypes<DoTestsMetafunction>{}, 71 NonTrivialTypes::ApplyTypes<DoTestsMetafunction>{}, 72 DoTestsMetafunction<TrivialMoveNonTrivialCopy, TrivialCopyNonTrivialMove>{} 73 ); 74} 75